Dana Yeger
Dana Yeger

Reputation: 711

C language: how to consider new line with scanf

So i have program that get numbers from user in single line for example:

2 1 2 3 4

The first number: 2 mean that the output should be matrix with 2 rows and 2 columns:

1 2
3 4

So this is how i am populate my aray:

int dim;
scanf("%d", &dim);
int *m = (int *)malloc(dim* dim* sizeof(int))

for (r = 0; r < dim; ++r)
{
    for (c = 0; c < dim; ++c)
    {
        scanf("%d", &m[dim * r + c]);
    }
}

Now i want to add some value check, in case the user input start with 2 the next input should contain 4 number () in a single line so in case the input is 2 1 2 3 i want to print error message but my problem is that after this input the scanf just ignored from the new line and wait.

Upvotes: 0

Views: 433

Answers (1)

If you know that your standard input is organized in lines, you could read each line entirely (probably with getline(3) like here or else with fgets) then parse that line appropriately in memory (keeping some internal pointer inside it, and using strtol(3) with its end pointer, or sscanf(3) with %n). BTW what exactly defines a line is operating system specific (Windows vs Linux vs MacOSX have different definitions and line terminators).

If you are not sure that the input is organized in lines, you'll use standard parsing techniques (e.g some recursive descent parser), probably with a single token of look ahead.

In all cases, you'll better specify on paper your file format. A simple EBNF notation is a good specification for most parsers.

Your current code is wrong, because you don't test against failure of scanf. You need to test its returned scanned item count. BTW, it is also wrong to use malloc without testing its failure, and you probably should use calloc not malloc because you should prefer zeroed memory.

Notice that scanf with %d (or better yet, " %d") is skipping spaces, including newline characters ending input lines. In other words, your scanf don't care about lines, as you say you want to.

Compile your code with all warnings and debug info (so gcc -Wall -Wextra -g with GCC) and use the debugger gdb to run it step by step and understand what is happening. Spend more time in reading documentation (notably of standard C functions, and of your software tools: compiler, debugger, ... that you would use on the command line).


BTW, terminals are complex (virtual) devices. On my Linux system, they could be line buffered by the kernel's line discipline. You might read the tty demystified and consider using readline(3) or ncurses (if you are sure to read from the terminal). Using fgets, getline and other stdio(3) functions is enough only if you are just reading from stdin and don't care about pseudo-terminals vs redirections or command pipelines. See also isatty(3).

(the last above paragraph is specific for Linux, and probably not for newbies. IMHO terminals are very complex, once you dive into details.)

Upvotes: 2

Related Questions