Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

Kevin9542

macrumors newbie
Original poster
Dec 29, 2014
9
0
Greetings,

I'm a beginner C programmer, studying computer science. I've come across sublime text 2 and i like it alot, although i can't seem to get it to work properly. Since im on Mac OS X Mavericks, running C code in sublime text seems to ignore scanf, although it builds correctly.

I've tried the same code on Xcode and it works perfectly fine.

I had to make a game as a c project and it relies on user input, does anyone know how i could fix this?


Thanks,
Kevin
 
Although I have never used Sublime text to "run" C code, presumably it somehow integrates a compiler and small shell? In any case, chances are that the problem lies elsewhere. scanf for example has quite a few pitfalls that is easy to fall into, so if you can, post your code here using the code tag (#).
 
Sublime Text is just a text editor like a more advanced form of Textedit on the mac. You can not compile code with it like you do in xcode. You can write it in Sublime Text and then compile it with Terminal.
 
This program for example will wait for user input in both Xcode and using gcc in the terminal manualy. Although in sublime text 2 it builds, shows up in a window in the bottom saying straight away a random value , skipping user input and instantly terminating the program. Image is after the code.

Code:
#include <stdio.h>

int main(){
	int x;

	printf("Enter a value : ");
	scanf("%d",&x);

	printf("\nThe value entered was %d\n",x);
	
	return 0;

}

Screen_Shot_2014_12_29_at_17_44_00.png
 
This program for example will wait for user input in both Xcode and using gcc in the terminal manualy. Although in sublime text 2 it builds, shows up in a window in the bottom saying straight away a random value , skipping user input and instantly terminating the program. Image is after the code.

I'm stumped, that should work as far as I can tell. I got curious and Googled, and it seems like Sublime text doesn't support interactive input.

https://www.sublimetext.com/forum/viewtopic.php?f=3&t=14713
http://www.sublimetext.com/forum/viewtopic.php?f=3&t=5441
 
Code:
#include <stdio.h>

int main(){
	int x;

	printf("Enter a value : ");
	scanf("%d",&x);

	printf("\nThe value entered was %d\n",x);
	
	return 0;

}

One problem I see with that code is you're not checking the value returned by scanf() to see what it actually read, or whether it read anything at all.

If scanf() reads an EOF immediately, then it won't put anything into the variables you told it to read values for. Most likely, the number printed by the printf() is some random junk that happened to be in the uninitialized memory used to hold the variable 'x'.

From the man page for scanf:
https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man3/scanf.3.html
RETURN VALUES
These functions return the number of input items assigned. This can be fewer than provided for, or
even zero, in the event of a matching failure. Zero indicates that, although there was input available,
able, no conversions were assigned; typically this is due to an invalid input character, such as an
alphabetic character for a `%d' conversion. The value EOF is returned if an input failure occurs
before any conversion such as an end-of-file occurs. If an error or end-of-file occurs after conversion
sion has begun, the number of conversions which were successfully completed is returned.
 
I might not be that great of a programmer, i´ve just started programming 3 months ago. Still about your suggestion, i usualy add an empty space behind %c in scanf for characters, but as my teacher told me that it's not really needed to do that for digits. Why should i test what scanf returns if it will save a new value entered by the user in that variable?

Thanks
 
In some cases, if you for example read from a file you may not notice an error in scanf, random data may be indistinguishable from genuine input so the error propagates to new places. If your file contained a format error for example where 4 columns is expected, and one row only contains 3.
 
In some cases, if you for example read from a file you may not notice an error in scanf, random data may be indistinguishable from genuine input so the error propagates to new places. If your file contained a format error for example where 4 columns is expected, and one row only contains 3.

I see, so i should verify the return value of scanf everytime i use it? Or just for debugging purposes?
 
I might not be that great of a programmer, i´ve just started programming 3 months ago. Still about your suggestion, i usualy add an empty space behind %c in scanf for characters, but as my teacher told me that it's not really needed to do that for digits. Why should i test what scanf returns if it will save a new value entered by the user in that variable?

Thanks

Ask your teacher about detecting "no data" conditions (EOF), or checking for unexpected conditions in general (also called error checking, but it's not exclusively about detecting errors, per se).

If you compile and run your program as-is in Terminal, and instead of entering a number you press control-D (the key for EOF), then the program reads no data. Yet your program also proceeds to print the data that it didn't actually receive.

If you enter a non-number, such as the string "foo", then the program reads data, but is unable to convert it to a number. In both cases (EOF or non-digits), nothing is actually stored into the variable 'x'. The only indication that no number was read is in what scanf() returns.

The problem with not checking for or handling unexpected inputs is of little consequence in this trivial program. If no number is read, nothing bad happens. It simply prints a meaningless number and exits. No harm done. This becomes progressively less true as one's programs become less trivial.

I mention checking scanf's return value now, because it's good to begin the practice of handling EOF and other unexpected-data or no-data conditions with simple programs. Do it with trivial programs and you'll do it with non-trivial programs. Or at least understand the consequences of not doing it.
 
Ask your teacher about detecting "no data" conditions (EOF), or checking for unexpected conditions in general (also called error checking, but it's not exclusively about detecting errors, per se).

If you compile and run your program as-is in Terminal, and instead of entering a number you press control-D (the key for EOF), then the program reads no data. Yet your program also proceeds to print the data that it didn't actually receive.

If you enter a non-number, such as the string "foo", then the program reads data, but is unable to convert it to a number. In both cases (EOF or non-digits), nothing is actually stored into the variable 'x'. The only indication that no number was read is in what scanf() returns.

The problem with not checking for or handling unexpected inputs is of little consequence in this trivial program. If no number is read, nothing bad happens. It simply prints a meaningless number and exits. No harm done. This becomes progressively less true as one's programs become less trivial.

I mention checking scanf's return value now, because it's good to begin the practice of handling EOF and other unexpected-data or no-data conditions with simple programs. Do it with trivial programs and you'll do it with non-trivial programs. Or at least understand the consequences of not doing it.

Thanks for pointing this out, from my little to non-existent experience these little details are rarely mentioned, i will keep this in mind when making more programs involving the use of scanf.

Just going a little off-topic, for the past few weeks i've been programming in the evening in my now almost non-existent free time, and i am enjoying programming quite a bit. I am planning on going through with computer science, and im worried if all these little details will come with time or should go deeper in what every function really does?

Happy holidays,
Kevin
 
I see, so i should verify the return value of scanf everytime i use it? Or just for debugging purposes?

I think it depends somewhat on the situation and purpose, for your purpose right now, possibly not. But it can be helpful, take for example the case of file input. Say you have a file with comma separated integers where you expect 4 columns on each row, then a simple parser for such a file may look like this:

Code:
#include <stdio.h>

int main()
{
    int a,b,c,d, rv;

    while( (rv = scanf("%d,%d,%d,%d", &a,&b,&c,&d)) != EOF ) {
        if(rv != 4) {
            fprintf(stderr, "format error\n");
            return 1;
        }
        printf("%d, %d, %d, %d\n", a, b, c, d);
    }

    return 0;
}

testfile
Code:
1, 2, 3, 4
5, 6, 7, 8
9, 10, 11, 12
13, 14, 15

Test it by redirecting the file to stdin:
Code:
./a.out < testfile
1, 2, 3, 4
5, 6, 7, 8
9, 10, 11, 12
format error

As you can see the last row contains only three rows, try it while removing the error check in the loop and you will get the wrong result with no indication that there has been an error.
 
I think it depends somewhat on the situation and purpose, for your purpose right now, possibly not. But it can be helpful, take for example the case of file input. Say you have a file with comma separated integers where you expect 4 columns on each row, then a simple parser for such a file may look like this:

Code:
#include <stdio.h>

int main()
{
    int a,b,c,d, rv;

    while( (rv = scanf("%d,%d,%d,%d", &a,&b,&c,&d)) != EOF ) {
        if(rv != 4) {
            fprintf(stderr, "format error\n");
            return 1;
        }
        printf("%d, %d, %d, %d\n", a, b, c, d);
    }

    return 0;
}

testfile
Code:
1, 2, 3, 4
5, 6, 7, 8
9, 10, 11, 12
13, 14, 15

Test it by redirecting the file to stdin:
Code:
./a.out < testfile
1, 2, 3, 4
5, 6, 7, 8
9, 10, 11, 12
format error

As you can see the last row contains only three rows, try it while removing the error check in the loop and you will get the wrong result with no indication that there has been an error.

I understand what you are saying, it gives an error (in this case) when scanf doesn't get what it wants to get, although i haven't gone through File management in C yet, started a little bit at home, but by the end of next week i will have more time to dive into these things ;)

Thanks for everything,
Kevin
 
Just a wild guess, but Sublime Text could be running the program in an environment without a standard input stream, so scanf() does nothing. It seems unlikely to me that Sublime Text would give you a fully featured terminal window that can take input.
 
There's discussion about handling errors such as EOF. I never use scanf() anyway or have bothered figuring out the best way to use it. No bounds checking, sometimes a security problem, and too annoying to check for errors. I just use fgets() on stdin then read the buffer however I want, and it's very simple in this case to use atoi(). But I'm not a real professional, so maybe someone with more experience would disagree.
 
Last edited:
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.