Why is this C for-loop not working properly? - c

int main()
{
int t, i;
int *nums;
scanf("%d", &t);
nums = malloc(t * sizeof(int));
for(i = 0; i < t; i++)
{
scanf("%d", &nums[i]);
}
printf("hey");
}
For some reason, it hangs, waiting for more input! Any ideas?

This code is correct, except for the fact that you're not freeing your memory (not a big issue for this simple code) and you're not checking scanf for errors, which may be the cause of your problem.
A better implementation with error checking and correct memory handling is described below:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int t, i, ret;
int *nums;
ret = scanf("%d", &t);
if(ret != 1)
{
/* something wrong */
}
nums = malloc(t * sizeof(int));
if(nums==NULL)
{
/* memory error */
}
for(i = 0; i < t; i++)
{
ret = scanf("%d", &nums[i]);
if(ret != 1)
{
/* something wrong */
}
}
free(nums);
printf("hey");
return 0;
}

Just a guess here...
But I'm guessing you ran it and entered :
4
1234
For example, you put in 4 and then 1234 and it hangs. Well, that would be because 1234 is the first number and not 4 distinct numbers so its waiting for the second number. You have to press enter or some such delimiter between each number.
Try this set of inputs instead:
4
1234
29
4
5
You should get :
hey
Pro grammatically, you should be checking return values from your function calls. Make sure malloc didn't return zero. Make sure scanf returns the number of inputs you expected to read. Add in printouts to make sure the values it read in are what you expected/wanted to read in.
EDIT :
Guessing you have a typo in the program which isn't displayed here. such as :
scanf("%s", &t);
Or you are getting the 'hey' and just not seeing it.
[ov#MARVIN sotest]$ ./a.out
5 5 4 3 23 1
hey[ov#MARVIN sotest]$
See the 'hey' is sort of hidden in my prompt because you are missing the '\n' new line in the printout?

Remember to flush when you are done.
In chat, OP's comments "No... BTW, if I add a printf in the loop that prints the current input, it prints everything except from the last one...". This hinted that the issue was on the final output.
The following sends data out to be printed. But stdout is typically buffered. Actual output may not occur until sometime later. Output is flushed when 1) output contains an end-of-line '\n', 2) fflush() is called 3) the program ends. I am surprised output did not appear when the program ended, but possibly OP's true code differs from the post.
printf("hey");
Change to
printf("hey\n");
Or #Cool Guy
printf("hey");
fflush(stdout);
BTW: This is also hinted in #Diversity answer.
Note: Always a good idea to check the result of scanf()
// scanf("%d", &t)
if (1 != scanf("%d", &t)) Handle_BadInput_or_EOF();

Related

My program creates a file named date.in but it is not inserting all the numbers

Write a C program that reads from the keyboard a natural number n
with up to 9 digits and creates the text file data.out containing the
number n and all its non-zero prefixes, in a single line, separated by
a space, in order decreasing in value. Example: for n = 10305 the data
file.out will contain the numbers: 10305 1030 103 10 1.
This is what I made:
#include <stdio.h>
int main()
{
int n;
FILE *fisier;
fisier=fopen("date.in","w");
printf("n= \n");
scanf("%d",&n);
fprintf(fisier,"%d",n);
while(n!=0)
{
fisier=fopen("date.in","r");
n=n/10;
fprintf(fisier,"%d",n);
}
fclose(fisier);
}
Few things:
Function calls may return error. You need to check that every time.
fisier=fopen("date.in","w");
This should have been followed by an error check. To understand more on what it return, first thing you should do is read the man page for that function. See man page for fopen(). If there is an error in opening the file, it will return NULL and errno is set to a value which indicates what error occurred.
if (NULL == fisier)
{
// Error handling code
;
}
Your next requirement is separating the numbers by a space. There isn't one. The following should do it.
fprintf(fisier, "%d ", n);
The next major problem is opening the file in a loop. Its like you are trying to open a door which is already open.
fisier=fopen("date.in","r");
if(NULL == fisier)
{
// Error handling code
;
}
while(n!=0)
{
n=n/10;
fprintf(fisier,"%d",n);
}
fclose(fisier);
A minor issue that you aren't checking is the number is not having more than 9 digits.
if(n > 999999999)
is apt after you get a number. If you want to deal with negative numbers as well, you can modify this condition the way you want.
In a nutshell, at least to start with, the program should be something similar to this:
#include <stdio.h>
// Need a buffer to read the file into it. 64 isn't a magic number.
// To print a 9 digit number followed by a white space and then a 8 digit number..
// and so on, you need little less than 64 bytes.
// I prefer keeping the memory aligned to multiples of 8.
char buffer[64];
int main(void)
{
size_t readBytes = 0;
int n = 0;
printf("\nEnter a number: ");
scanf("%d", &n);
// Open the file
FILE *pFile = fopen("date.in", "w+");
if(NULL == pFile)
{
// Prefer perror() instead of printf() for priting errors
perror("\nError: ");
return 0;
}
while(n != 0)
{
// Append to the file
fprintf(pFile, "%d ", n);
n = n / 10;
}
// Done, close the file
fclose(pFile);
printf("\nPrinting the file: ");
// Open the file
pFile = fopen("date.in", "r");
if(NULL == pFile)
{
// Prefer perror() instead of printf() for priting errors
perror("\nError: ");
return 0;
}
// Read the file
while((readBytes = fread(buffer, 1, sizeof buffer, pFile)) > 0)
{
// Preferably better way to print the contents of the file on stdout!
fwrite(buffer, 1, readBytes, stdout);
}
printf("\nExiting..\n\n");
return 0;
}
Remember: The person reading your code may not be aware of all the requirements, so comments are necessary. Secondly, I understand english to a decent level but I don't know what 'fisier' means. Its recommended to name variables in such a way that its easy to understand the purpose of the variable. For example, pFile is a pointer to a file. p in the variable immediately gives an idea that its a pointer.
Hope this helps!
To draw a conclusion from all the comments:
fopen returns a file handle when successfull and NULL otherwise. Opening a file twice might result in an error (it does on my machine), such that fisier is set to NULL inside the loop. Obvioulsy fprintf to NULL wont do anything.
You only need to call fopen once, so remove it from the loop. After that it will work as intended.
It's alwas good to check if the fopen succeeded or not:
FILE *fisier;
fisier=fopen("date.in","w");
if(!fisier) { /* handle error */ }
You print no spaces between the numbers. Maybe that's intended, but maybe
fprintf(fisier,"%d ",n);
would be better.

getchar() returns a character that isn’t a newline after I press enter

This is the code:
#include <stdio.h>
int main()
{
int i = 0;
while(getchar() != '\n') {
printf("\n%d\n", i);
i++;
}
printf("second printf: %d\n", i);
return 0;
}
The expected ouput after I press enter only is:
second printf: 0
instead of:
0
second printf: 1
Why is this happening ?
I am on linux Ubuntu MATE.
So I got some information about anas firari's environment by reading his other questions. This involves some measure of physic debugging.
You are getting input of \r\n when you type a newline because your terminal is in raw mode. Older shells used to choke on this by treating \r as something that isn't whitespace, but newer ones actually work ok.

Please help in finding the error in my program

I know the program I am posting is very basic but I am unable to find the error. I rechecked everything but despite no compilation error, the output is not coming.
#include<stdio.h>
#include <stdlib.h>
int main()
{
int i;
while(1)
{
if((scanf("%d",&i))!=42)
{
printf("%d",i);
}
else
{
break;
}
}
return 0;
}
Thank You for your time and consideration.
scanf does not return the value entered. It returns the number of inputs matched. So your check for 42 is incorrect. It will return 1 if an integer was assigned to i, or 0 if there was invalid input. If you want to exit the loop when the user enters 42, you should explicitly test if (i == 42).
As simonc mentioned, The reason you're not getting any output is because printf("%d",i); is not printing a newline "\n" after the number, and the standard out (stdout) stream is line-buffered. That means the standard library is going to continue to buffer up your printfs until a newline is encountered. At this point the buffer will be flushed to the console.
The solution is to add the newline (which is probably what you desire anyway): printf("%d\n",i); Alternatively, you could call fflush(stdout) to tell the std library to flush the buffered content to the console immediately. Or, writing to stderr will output immediately, because it is unbuffered.
This should demonstrate:
#include <stdio.h>
int main()
{
int i;
while(1) {
fprintf(stderr, "Enter a number (or 42 to quit): ");
if((scanf("%d",&i)) != 1) {
fprintf(stderr, "Invalid input.\n");
continue;
}
if (i==42)
break;
printf("Number provided: %d\n", i);
}
return 0;
}
Output:
$ ./a.exe
Enter a number (or 42 to quit): 17
Number provided: 17
Enter a number (or 42 to quit): 42
$
You are comparing the scanf function's return value to 42, not the variable i's value.
maybe you should read this
http://www.cplusplus.com/reference/cstdio/scanf/?kw=scanf

Why is scanf printing its input in the Nios 2 IDE?

A very simple program is not even working.
int main ()
{
int n;
while (scanf("%d", &n) > 0)
return 0;
}
The above I would expect to only read to input but it also prints the input:
2
2
3
3
I would have expected the above behavior if I had also this line in the while loop but I don't:
printf("%d\n", n);
Can you explain?
Update
There is nothing in the answers that explain why this is happening. And no setting in the Nios 2 IDE for local echo turned on or off. And if there were it probably would not be dafeult causing unexpected output. And this program also prints its input:
#include <stdio.h>
int main ()
{
int n;
while (scanf("%d", &n) > 0)
;
return 0;
}
So this Nios 2 IDE which is based on Eclipse is nobody's choice since you cannot figure out why it is behaving in a way it shouldn't
2 candidates
Your terminal I/O has an unneeded local echo turned on. Thus an OS issue, not a issue of this program.
Missing ; at end of while() invokes expected results. The code as posted should simple read some input and then immediately exit. This is not as the OP recounts. Suspect it is a mis-transcription of the problem.
[edit] Now see all of #alk solution. Certainly something is in the OP's real code that is not visible in the post -maybe due to mixed \r and \r\n and \n?
// Was it a typo that the OP did not have a;at the end?
while (scanf("%d", &n) > 0)
Most probably your code looked like this:
int main ()
{
int n;
while (scanf("%d", &n) > 0) printf("%d\n", n);
return 0;
}
// ------------------------------------------------------------------ scroll right >>> --------------------------------------------------
scanf() returns integer which is number of parameters given as input. In your case scanf("%d",&n) returns 1.
You can check this as ref-
http://cboard.cprogramming.com/c-programming/119407-scanf-return-values.html

Using putchar and printf together in the same C Program?

I've written a small C program where I wanted to display the numeric ASCII value that corresponds to certain key presses.
My code follows. The problem is, after running the program, it accepts input, but doesn't do anything else. It doesn't even reach the first printf statement. I can't figure out what the issue is - is there a problem with mixing the getchar() function with the printf() function in the same program?
#include <stdio.h>
int main() {
const int numKeys = 256;
int keys[numKeys];
int i;
for (i = 0; i < numKeys; i++) {
keys[i] = 0;
}
printf("\n Start pressing some keys!\n\n");
int c;
while ((c = getchar()) != EOF) {
printf(" CAPTURED: %d\n", c);
keys[c]++;
}
printf("\n\n ** RESULTS ** \n\n");
for (i = 0; i < numKeys; i++) {
if (keys[i] != 0) {
printf(" Key with value %d was called %d times.", i, keys[i]);
}
}
}
I should clarify that I have a Windows XP Pro machine, with Cygwin installed. I use Cygwin for my development space, so I wonder if there is something different when running this type of program in that environment.
I found the problem. I think you want to use
while ((c = getchar()) != EOF && c != '\n')
Instead if you want to have it print the results after the person hits enter/return.
problem 1 : getting to printf(" CAPTURED: %d\n", c); without having to press the Enter key
solution : is by using getche() in while loop.
problem 2 : getting to 'printf("\n\n ** RESULTS ** \n\n");' or essentially breaking while loop?
solution : you cannot. you will never get EOF as long as you read from keyboard.
workaround : close stdin or use a escape character other than EOF.
EDIT : workaround2 :
->use getchar() itself. but to print those entered char u need to press Enter key. now on windows ctrl+z gives EOF but this should be the **FIRST** input on the line after you press Enter key. well this is not a good solution.
if you want a "Press key display times pressed scenario. there is just no simple way(AFAIK)"
I believe that the first printf statement gets executed, but due to buffering is not displayed on the screen immediately. Use fflush(stdout) to send the contents of the buffer to the screen. Ie:
printf("\n Start pressing some keys!\n\n");
fflush(stdout);

Resources