Search code examples
cstdinfgetsstrtokstat

Reading in filenames from stdin c


While this is a very basic problem that should be easy to solve, I haven't been able to figure it out. I am attempting to read in a string containing filenames broken up by whitespaces from stdin. While it appears to read all the filenames correctly, when I use stat() on the filenames it always fails on the last file. The files all exist and it always fails on the last one, for example if the stdin is "file.txt thisFile.txt thisFile.txt", if I ask it to print the input to stdout it will print "file.txt thisFile.txt thisFile.txt", but when I use stat() on the files it will work for all but the last file. I believe it has something to do with the way I am reading in the files, any help is appreciated. P.S. if I end the output with a whitespace "file.txt thisFile.txt thisFile.txt " it will stat all the files with no issue. However due to other portions of the program and other files it needs to work with via pipes the extra whitespace is not a valid format for the input.

char *input = 0;
char buffer[10];
size_t curMax = 0;
size_t curLen = 0;
fprintf(stderr, "accessed waiting for input\n");
while(fgets(buffer,sizeof(buffer),stdin)!=0)
{
    size_t bufLen = strlen(buffer);
    if(curLen+bufLen+1>curMax)
    {
        size_t newLen = curMax*2+1;
        if(bufLen+1>newLen)
            newLen=bufLen+1;
        char *extra = realloc(input, newLen);
        if (!extra)
            break;
        input = extra;
        curMax = newLen;
    }
    strcpy(input+curLen,buffer);
    curLen+=bufLen;
}

fprintf(stderr, "accessed input received: %s\n", input);
int i = 0;
int count = 1;
for (i = 0; i < strlen(input); i++){
    if (input[i] == ' ')
        count++;
}
char * fileNames[count];
char * pch = strtok(input, " \0FEOFfeof\n");
int j = 0;
for (j = 0; pch != NULL; j++){ //Read file names
    fileNames[j] = (char *)malloc(strlen(pch));
    strncpy(fileNames[j],pch, strlen(pch));
    pch = strtok(NULL, " \0FEOFfeof\n");
}

Solution

  • fgets() leaves the '\n' at the end of the read string.

    So you just need to remove it, an example would be

    while (fgets(buffer, sizeof(buffer), stdin) != NULL)
     {
        size_t length
        length = strlen(buffer);
        if (buffer[length - 1] == '\n')
            buffer[length - 1] = '\0';
        ...
     }