upd .: Renamed the question. From under the terminal code works.

I attempted to migrate to Linux (xubuntu 12.10 x64) with Windows. First of all, the QTcreator and MonoDevelop development environments were installed and a simple test program was written. The essence of the program is to give the user n random numbers from 1 to m until you enter 0. Code:

#include<stdio.h> #include<stdlib.h> #include<time.h> int dN(int N); void MdN(int M, int N); int main(int argc, char ** argv) { int m = 1, n = 0; int c; srand(time(NULL)); while (m != 0) { printf("\nВведите два числа (количество и количество граней дайсов) или 0 для выхода\n"); m = 0; c = scanf("%d", &m); if (c != 1) { puts("Ошибка ввода"); return 0; } if (m != 0) { n = 0; while (n == 0) { printf("\b\bd"); c = scanf("%d", &n); if (c != 1) { puts("Ошибка ввода"); return 0; } } MdN(m, n); } } printf("\n"); return 0; } int dN(int N) { return rand()%N + 1; } void MdN(int M, int N) { int s = 0, tmp; while (M>0) { s += tmp = dN(N); printf("+%d", tmp); M--; } printf("=%d;\r \n", s); } 

In both environments, the code did not work correctly. In QtCreator, the program has infinitely requested input (including character type). In MonoDevelop, the program did not request (and did not expect) input, but output

 \nВведите два числа (количество и количество граней дайсов) или 0 для выхода\n Ошибка ввода 

(done with c == EOF).

Installed the environment through the Ubuntu Application Center, did not change the default settings.

// there was an even simpler code with the same problem

  • Try enabling ctype.h - renegator
  • It did not affect the operation of the program. - bessgeor
  • @bessgeor, well, you directly interested me (the last little code). And what do you expect from him? If printing the entered number, add %d to the appropriate printf() . I also advise you to end the output with the symbol '\\ n'. - avp
  • I forgot% d due to inexperience and I was in a hurry. Corrected this, the situation with the incorrect operation of the program is preserved. Now I’ll try to apply the compiler flags, as KoVadim advised, maybe I can see the cause of the problem. - bessgeor
  • one
    @bessgeorg, now replace in if (c == 1) {puts ("Input error"); .... c == 1 to c! = 1, you see, and it will be better. - avp

4 answers 4

Looked at the code, it became scary. Here is my version (written in the forehead, in fact it would be possible to make it into separate functions)

 #include<stdio.h> #include<stdlib.h> #include<time.h> #include <ctype.h> int dN(int N) { srand(time(NULL)); return rand()%N + 1; } void MdN(int M, int N) { printf("==== MdN(%d,%d)===\n", M, N); // это для отладки int s = 0, tmp; if (N == 0) // защита, Ваш код падал при нуле return; while (M>0) { s += tmp = dN(N); printf("+%d", tmp); M--; } printf("=%d;\r \n", s); } int main() { int m = 0; int n = 0; while (1) { printf("Enter two numbers (MdN) or zero to exit\n"); int r = scanf("%d", &m); // ввод первого if (r != 1) { puts("first number is not numer\n"); break; } if (m == 0) { // пользователь ничего не ввел либо ввел один ноль puts("exit\n"); break; } // удалось прочитать только одно число. Попробуем прочитать ещё одно r = scanf("%d", &n); if (r != 1) { puts("ups, second number is not number\n"); break; } MdN(m,n); } printf("end\n"); return 0; } 

scanf returns the result and will correctly check what it returned. In fact - returns the number of variables that were able to read. 0 - if not read anything. Those variables that could be read will have values. If something strange happens, scanf return -1 (honestly, the constant EOF ).

You can enter as sscanf("%d %d", &m, &n) . But if the user enters only one zero, the code will wait until one more character is entered. Therefore, I have broken the input into two parts.

Oddly enough, the code did not work correctly in both environments.

it is logical, since with 99% probability the compiler is the same - gcc.

For your case, getchar () would fit a lot with checking the entered value.

very bad advice. With int still make check, and with float ?

Why does it work in Visual studio? there is a suspicion that there sscanf("%d %d", &m, &n) when entering a single number and a line break returns 1 and a filled m .

upd

Given the recent changes in the example in question. If you are just starting to learn C and make a lot of mistakes (often elementary), then the compiler needs to hint that you need to be stricter. Yes, he will quibble over trifles, but for the first time it is.

I recommend such a set

 -std=c99 -pedantic -Wall -Wshadow -Wpointer-arith -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes 

How to use:

  • if it's in the console, then just `gcc filename.st -st = c99 -pedantic -Wall -Wshadow -Wpointer-arith -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes
  • if it is monodevelop. Select your project in the "decision tree" on the left, click the right one, "properties", in the "project properties" window, find "Code generation", select a tab with the same name and see the "Extra Compiler Options" window at the bottom, where you insert the above list .
  • In QtCreator you need to open the pro file and add a line like QMAKE_CFLAGS = -std=c99 -pedantic -Wall -Wshadow -Wpointer-arith -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes

What do these flags mean?

  • std=c99 follow standard c99. Now there are others, but this one is more industrial (but this is my opinion)
  • pedantic be more sensitive
  • Wall includes a large set of checks. For example, it will stick to the code of the form if (a = 0) (some amateurs like to treat it by turning over the conditions, and some use it for conscious entanglement). This option also includes -Wformat , which causes the compiler to recalculate the parameters of the printf/scanf type functions and swear if they are missing or the types do not match.
  • Wshadow find fault when the function uses overlapping variables. For example, inside a function, a variable is declared whose name matches the parameter. In some cases it can lead to hilarious errors.
  • Wpointer-arith in newer versions is already included in -pedantic . Carp when cheating with pointer arithmetic.
  • Wcast-qual when casting is done, which is potentially dangerous. this often climbs with newbies when they learn to work with strings in the style of.
  • Wstrict-prototypes attach to int main() , since it is desirable to write int main(int argc, char ** argv) .
  • Wmissing-prototypes will require you to define prototypes of the functions used. That is, add lines of the form int dN(int N); .

Of course, some will find these things absurd and disturbing (especially for "advanced programmers"). But I occasionally include such kits in my projects and see if nonsense has come out - it is easy to make a typo.

At first, I recommend eliminating all these compiler comments.

  • In this topic, reading float is not worth it, so getchar () is quite appropriate. - margosh
  • and make an overflow check, and make input of negative numbers? Entering via getchar in this case is a bicycle. - KoVadim
  • one
    In this case, it should not give the problem described by the author. - KoVadim
  • one
    The compiler keys that I brought in will try to uncover some of the errors so that the vehicle doesn’t ask about elementary errors. TC writes that he does not like and it is definitely not connected with srand. - KoVadim
  • one
    @bessgeor, well, what really doesn't work for you? Here's your code (did not touch anything in it), compiled and launched: avp @ avp-ubu1: ~ / hashcode $ gcc t22.c avp @ avp-ubu1: ~ / hashcode $ ./a.out Enter two numbers (MdN ) or zero to exit 3 3Enter non-zero N4 2 + 2 + 2 = 6; Enter two numbers (MdN) or zero to exit 5 5Enter non-zero N6 2 + 2 + 2 + 2 + 2 = 10; Enter two numbers (MdN) or zero to exit 0 0avp @ avp-ubu1: ~ / hashcode $ As you can see, I / O is working. This is Linux (Ubuntu 12.04.2, gnome-terminal). With \\ n you, of course, are not friends, but in principle it works. - avp

Most likely, your problem lies in the scanf () function, since This function completes the reading of the number when it encounters the first non-numeric character ( link ), respectively, in your main loop:

  1. the variable m remains equal to its previous value,
  2. after the entered character tries to be counted again, is not read again, and either the previous value or garbage remains in n,
  3. actions are performed for inadequate m and n, but the character entered is not removed from the input stream, and a loop occurs.

You also have an error - you do not check the value stored in n, and in the dN () function divide it, although no one bothers to enter the second requested number - 0.

  • Redone (changed the code in question) input for using getchar (). The problem is preserved in the same form, except that in MonoDevelop looping no longer occurs and the output occurs only once (since in the body of the loop, before entering m, it equals 0, but no input occurs). - bessgeor
  • compiled with getchar () in gcc, everything is normally entered there ... try even easier to start the runtime just by entering the chillel and then printing it. KoVadim is right, you should still use the same scanf (), but with checking the result in order to avoid looping. - margosh
  • gcc generates an executable file, the launch of which does not lead to anything - bessgeor
  • @margosh, have you decided to make fun of a newcomer (this is about the advice to replace scanf with getchar)? - It is, of course, possible (in the end, your scanf will work), but still it’s much easier to enter numbers to learn how to use scanf from the library. - avp
  • @avp, no, I decided that the author simply checks the input, and once using scanf () it wasn’t possible to figure it out right away (he was looping everything in the original version), it’s easier to use getchar (), but if the root of the problem is in reading the numbers, then she is uncomfortable. I will correct the answer so that no one else can do it. - margosh

Why does it work in Visual studio?

In melkomyagky all as not people

In general, I advise you to compile gcc from the command line.

  • one
    @akalend: do you think that the fact that the program does not work is normal, so should it be with people? - VladD

Good day! Regarding your simple task (enter a number, print a number), you are not using the printf function correctly - you forgot to pass the format string, the standard says that

The program will have undefined behavior.

What do you have on different platforms (freezes, does not output, etc.) Here is the corrected version:

 #include <stdio.h> int main() { int a, b; printf("test output\n"); b = scanf("%d", &a); if (b == EOF) puts("input error"); // не забываем %d! printf("input test: %d", a); return 0; } 

Now, regarding the question itself, I didn’t quite understand what exactly is wrong in your code? I just have the corrected code of your program working like normal, maybe I didn’t catch something?

  • In a small task, fixing% d did not help. The problem is the following: in all versions of the code that can be compiled a) gcc generates an executable file, the launch of which leads nowhere to nothing what can (what is not definitely false conditions, for example, 1! = 1). For example, the execution of your code above leads to this conclusion: test output input error input test: 0 - bessgeor
  • Look, maybe it will help: stackoverflow.com/questions/3255035/qt-creator-run-in-terminal - progzdeveloper