csystem-callslow-level-io

`read` in C hangs the program when string of length more than 16 entered


I made following program that uses read (system call in C) to get a string from user (of length lesser than 100).

#include<stdio.h>
#include <unistd.h>
#include <string.h>
int main() {
char *s;
int a = read(0, s, 100);
s[a-1] = '\0';
printf("\"%s\" \n read returned: %i; NUL at: %u", s, a, strlen(s));
return 0;
}

What I expected here is, it will get characters until user enters a new-line character. It will then replace that '\n' character by '\0', and print it.

The program works well until I enter 15 or less characters in stdin, but stops working when there are more than 16 characters.

My inputs are as follows:

E:\My Files\Codes>a.exe
1234567890123456
"1234567890123456"
 returned = 17; length = 16
E:\My Files\Codes>a.exe
12345678901234567
[My program hanged on this input.]

Why does it only hangs on 16? What is special in this 2^2? Post script: I used the string.h just to get the length of the string. Once my program starts working good, I will remove it.


Solution

  • I have been testing your code. The faults is: You have a pointer which points nowhere. I solve it reserving and allocating memory for your string (char array). I will post the working code:

    #include <stdlib.h> // It is needed for malloc, free, etc...
    #include <stdio.h>
    #include <unistd.h>
    #include <string.h>
    
    int main() {
        char *s = malloc(100*sizeof(char)); // Allocate memory with malloc
        int a = read(0, s, 100);
        s[a-1] = '\0';
        printf("\"%s\" \n read returned: %i; NUL at: %u", s, a, strlen(s));
        free(s); // You need liberate memory before exit
        return 0;
    }
    

    Also, other way to solve this, without dynamic memory is:

    #include <stdio.h>
    #include <unistd.h>
    #include <string.h>
    
    int main() {
        char s[100]; // s is a char array of 100 elements
        int a = read(0, s, 100);
        s[a-1] = '\0';
        printf("\"%s\" \n read returned: %i; NUL at: %u", s, a, strlen(s));
        return 0;
    }