t.elazari
t.elazari

Reputation: 280

how to read input string until a blank line in C?

first of all i'm new to coding in C.

I tried to read a string of unknowns size from the user until a blank line is given and then save it to a file, and after that to read the file.

I've only managed to do it until a new line is given and I don't know how to look for a blank line.

#include <stdio.h>
#include <stdlib.h>

char *input(FILE* fp, size_t size) {
    char *str;
    int ch;
    size_t len = 0;
    str = realloc(NULL, sizeof(char)*size);
    if (!str)return str;
    while (EOF != (ch = fgetc(fp)) && ch != '\n') {
        str[len++] = ch;
        if (len == size) {
            str = realloc(str, sizeof(char)*(size += 16));
            if (!str)return str;
        }
    }
    str[len++] = '\0';

    return realloc(str, sizeof(char)*len);
}

int main(int argc, const char * argv[]) {
    char *istr;
    printf("input string : ");
    istr = input(stdin, 10);
    //write to file
    FILE *fp;
    fp = fopen("1.txt", "w+");
    fprintf(fp, istr);
    fclose(fp);

    //read file
    char c;
    fp = fopen("1.txt", "r");
    while ((c = fgetc(fp)) != EOF) {
         printf("%c", c);
    }

    printf("\n");
    fclose(fp);

    free(istr);
    return 0;
}

Thanks!

Upvotes: 0

Views: 3971

Answers (3)

blatinox
blatinox

Reputation: 843

A blank line is a line which contains only a newline, right ? So you can simply keep the last 2 characters you read. If they are '\n', then you have detected a blank line : the first '\n' is the end of the previous line, the second one is the end of the current line (which is a blank line).

char *input(FILE* fp, size_t size) {
    char *str;
    int ch, prev_ch;
    size_t len = 0;
    str = realloc(NULL, sizeof(char)*size);
    if (!str)return str;
    while (EOF != (ch = fgetc(fp)) && (ch != '\n' && prev_ch != '\n')) {
        str[len++] = ch;
        if (len == size) {
            str = realloc(str, sizeof(char)*(size += 16));
            if (!str)return str;
        }
        prev_ch = ch;
    }
    str[len++] = '\0';

    return realloc(str, sizeof(char)*len);
}

Note that parenthesis around ch != '\n' && prev_ch != '\n' are here to make the condition more understandable.

To improve this, you can keep your function that reads only a line and test if the line returned is empty (it contains only a '\n').

Upvotes: 1

rrauenza
rrauenza

Reputation: 6973

I would restructure your code a little. I would change your input() function to be a function (readline()?) that reads a single line. In main() I would loop reading line by line via readline().

If the line is empty (only has a newline -- use strcmp(istr, "\n")), then free the pointer, and exit the loop. Otherwise write the line to the file and free the pointer.

If your concept of an empty line includes " \n" (prefixed spaces), then write a function is_only_spaces() that returns a true value for a string that looks like that.

While you could handle the empty line in input(), there is value in abstracting the line reading from the input termination conditions.

Upvotes: 2

duncan
duncan

Reputation: 1161

Why not use a flag or a counter. For a counter you could simply increase the counter each character found. If a new line is found and the counter is 0 it must be a blank line. If a new line character is found and the counter is not 0, it must be the end of the line so reset the counter to 0 and continue.

Something like this:

int count = 0;
while ((ch = fgetc(fp)) != EOF)
{
    if(ch == '\n')
    {
        if(count == 0)
        {
            break;
        }
        count = 0;
        str[len++] = ch;
    }
    else
    {
        str[len++] = ch;
        ch++;
    }
}

Another way would be to simply check if the last character in the string was a new line.

while ((ch = fgetc(fp)) != EOF)
{
    if(ch == '\n' && str[len - 1] == '\n')
    {
        break;
    }
}

Upvotes: 1

Related Questions