Odd printing behavior in C - c

I'm trying to print out comma seperated values in my C program, but I think I keep getting memory allocations instead.
When running from the command line, this happens.
1
49 this is the response
10 this is the response
1
49 this is the response
10 this is the response
Here is my program:
void main(){
int j;
int idnum;
j = 0;
char entry[99];
do{
idnum = get_field(entry);
j++;
}
while(idnum!='\n' && idnum!= ',' && j!= MAXTYPES);
int recur = 0;
while (recur != 4){
printf("%4d\n", entry[recur]);
recur++;
}
printf("\nEnd of Input\n");
}
int get_field(char entry[]){
int idnum;
char n;
int j = 0;
char temp[45];
while ((n=getchar())!= EOF){
printf("%d this is the response\n",n);
}
return idnum;
}

Problems I see:
In get_field, you have not initialized idnum and returning it from the function.
In get_field, the while loop to read the data is strange. I am not sure what you are trying to accomplish. However, you if type 1 and then press Enter, two characters are added to the input stream: '1' and '\n'. You are reading them as char, using getchar, and printing them as int (by using the "%d" format).
That explains the output you are getting.
49 is the decimal representation of '1'.
10 is the decimal representation of '\n'
The return type of getchar is int. You should change the type of n in get_field to int from char. That could be source of problems depending on the platform you are working in.

With %d you are printing the ASCII values. ASCII value of 1 is 49 and of \n is 10.
These are what you are getting.
You may want to print them with %c.

Since n is a char type data.So,you've to use %c instead of %d Like this:
printf("%c this is the response\n",n);

Related

why does the getchar() function not work here?

I'm trying to write C code where it takes in integer inputs, and prints them, unless the newline character ('\n') is entered.
But it never returns the value that I enter.
If I enter 6, I expect it to print 6 but it gives me 54. In fact whatever number I expect, it gives me 48+(my number). Please help!
Here's my code:
#include <stdio.h>
int main(int argc, char *argv[])
{
int counter = 0;
int num;
while (counter <=1)
{
num = getchar();
if (num == '\n')
{
break;
}
counter+=1;
printf("%d", num);
}
return 0;
}
It looks like an ASCII code for your characters is printed.
Use %c to print one character:
printf("%c", num);
Or subtract '0' (the character code of 0) from the value to convert digit characters to the corresponding integer:
printf("%d", num - '0');
That's because you are printing the ascii equivalent of the integer. You can either typecast the input you get, i.e, int(num) after you read it or you can use scanf like this:
int num;
scanf("%d", &num);

getchar vs scanf: why won't getchar work?

I wrote a simple program to input a number and return any value which when divided by it will return a remainder of 3.
I'm currently reading K&R and it doesn't teach scanf until something like Chapter 7 so I tried to use getchar. It doesn't work, but scanf does. What am I doing wrong?
int main()
{
int c, i;
printf("Input an integer: ");
//c = getchar();
scanf("%d", &c);
for (i = 1; i <= 100; i++) {
if ((i % c) == 3) {
printf("%d\n", i);
}
}
return 0;
}
Optional side question: It seems like people here have been advising not to start with K&R. What might be a better alternative for a beginner?
This:
scanf("%d", &c);
Is requesting scanf() to read an integer value from standard input. The scanf() function will read from standard input as much characters as needed, and then parse them into an integer, storing the value in the variable c (i.e. at the address pointed by &c). The return value of scanf() also communicates the number of correctly parsed items, so in this case you should check if the returned value is 1.
This:
c = getchar();
Is requesting getchar() to read a single character from standard input. The getchar() function will try to read a character, and will return it (casted to an int) in case of success. In case of error or end of file, the special integer value EOF will be returned. The fact that getchar() returns an int doesn't mean that the function will parse the input like scanf("%d", ...) does. Indeed, the return value has type int only because it's needed to distinguish a valid character from EOF.
To know more, refer to the manual pages for scanf and getchar using the man command, e.g. man scanf. Consulting manual pages is important to understand the semantics of a function. Always read the manual. Alternatively, you can look it up online: scanf(), getchar().
If you want to scan a single character using getchar() and convert it into an integer, then you can do the following:
#include <stdio.h> // getchar(), puts()
#include <ctypes.h> // isdigit()
int main(void) }
int c;
c = getchar();
if (c == EOF) {
puts("Error!");
return 1;
}
if (!isdigit(c)) {
puts("Character is not a digit!");
return 1;
}
int value = c - '0';
// value now holds the integer corresponding to the digit that was read from input
/* ... */
return 0;
}
Note: c - '0' works because characters representing digits have sequentially increasing values in the ASCII table (from 0x30 to 0x39). See also man ascii.
getchar reads one symbol from the inputs stream and returns it as its integer value of its internal representation or EOF.
So to read a number that has at least two digits you have to call getchar several times and then convert the symbols' representations to the corresponding integer number.
Opposite to getchar scanf tries to read a whole number as an integer if you specified the conversion format %d or similar specially designed to read numbers
Here is a demonstrative program that shows how your program can be implemented using getchar. In the program there is no check whether the user entered a too big number. You can add such a check yourself.
#include <stdio.h>
#include <ctype.h>
int main(void)
{
const unsigned int REMAINDER = 3;
printf( "Input a non-negative integer: " );
unsigned int n = 0;
for ( int c; ( c = getchar() ) != EOF && isdigit( ( unsigned char )c ); )
{
const unsigned int Base = 10;
n = Base * n + ( c - '0' );
}
if ( n > REMAINDER )
{
const unsigned int N = 100;
for ( unsigned int i = 0; i < N; i++ )
{
if ( ( i + 1 ) % n == REMAINDER ) printf( "%u ", i + 1 );
}
putchar( '\n' );
}
return 0;
}
The program output might look for example like
Input a non-negative integer: 10
3 13 23 33 43 53 63 73 83 93
As for books then it is always difficult to read a book on a language or technology which you are not familiar yet.

Adding values from a file to an array until a certain character

I am working on a program that uses file redirection to read in a file, read one character per line until I reach a '0', store the characters in an array , and sort that array (from largest to smallest). Anyway, I really only need help with reading the characters until the zero shows up. Below is the text file that I am reading in:
f
k
s
j
p
a
v
r
t
u
h
m
g
e
b
y
n
z
w
l
i
x
q
c
o
d
0
Below is the code I have so far:
int main(void)
{
int i=0;
char array[100];
while(fscanf(stdin, "%c", &array[i]) && array[i]!='0')
{
i++;
}
int N = (sizeof(array)/sizeof(array[0]));
for(i=0;i<N;i++)
{
printf("%c", array[i]);
}
return(0);
}
When I run this program, it prints out every line of the file, including the zero. It also prints out some really weird characters after the zero (using gcc compiler). What am I doing wrong?
You need to set N to the value of i, currently it will always be 100
You use i to keep track of how many items you've read, but then you overwrite the value of i in your loop and print out all 100 elements, whether you stored something there or not.
Use different variable for counting the element than you do for looping, and use the count as your loop limit.
int count=0;
char array[100];
while(fscanf(stdin, "%c", &array[count]) && array[count]!='0')
{
count++;
}
for(i=0;i<count;i++)
{
printf("%c", array[i]);
}
fscanf needs to skip the separator (enter or space), else it will be incorporated into your list. Adding a space fixes that.
#include <stdio.h>
#include <stdlib.h>
int sort (const void *a,const void *b)
{
return ((int)*((unsigned char *)a)) - ((int)*((unsigned char *)b));
}
int main (void)
{
unsigned char array[100],i=0;
while (fscanf(stdin," %c", &array[i]) && array[i] != '0')
i++;
qsort (array,i,1,sort);
while (i)
printf ("%c\n", array[--i]);
}
It may seem this program sorts the wrong way around but the printing loop also happens to print in reverse, so that solves it neatly. As the array is unsigned char, the sort routine casts this to int to prevent possible overflow.

Append numbers in C

How can I read six digits separately, and then append them?
For example:
I want to enter the following digits: 2 3 6 , 7 5
And the expected output would be: "236,75".
I have to do it with only one loop (to read the numbers), and I have to read the numbers with the type char.
Here's what I have so far:
#include <stdio.h>
int main()
{
char c;
char string [6];
printf("Introduce a number\n");
int i = 0;
while (i <=5) {
scanf("%c", &c);
string[i] = c;
i++;
}
printf("%c\n",string);
}
Try something like this:
char string [7];
printf("Introduce a number\n");
int i = 0;
while(i <=5){
scanf("%c", &c);
string[i] = c;
i++;
}
string[i] = '\0';
//printf("%s", string);
I added the '\0' character at string[6], just in case you need that for printing the values for example.
Also, I recommend you to read about cleaning the input buffer when obtaining input from stdin. Hope it helps.
For starters ensure that your int main() is actually returning an integer.
#include <stdio.h>
int main()
{
char c;
char string[7];
char* stringy = string;
printf("Introduce a number\n");
int i = 0;
while (i <=5) {
scanf("%c", &c);
string[i] = c;
i++;
}
string[i] = '\0';
printf("%s\n",stringy);
return 0;
}
Also you want to print your entire string out with a %s format specifier. This also means that you'll need to null terminate your string which can be done by setting the last character in your array to \0.
Also make sure your array has 7 indexes instead of 6, so everything can fit.
#include <stdio.h>
int main()
{
char c;
char string [7];
printf("Introduce a number\n");
int i = 0;
while (i <=5) {
scanf("%c\n", &c);
string[i] = c;
i++;
}
string[i] = '\0';
printf("result: %s\n",string);
return 0;
}
C strings end with a null character, that is '\0'. Therefore you should always append the null character to a character string as the last character since it determines the end of the string. Therefore the line string[i] = '\0'; is necessary (at the end of the while loop, the value of i will be 6, thus pointing to the last element of the character array).
Another correction to your code is the final printf(). You specified the format to be character format ("%c"), which will only output the first character of the string. You should change it to "%s" for printing the whole string.
This program should work since it is a valid C code. If you are having troubles with this code, then it is platform specific. I couldn't run this code on VS2012, but managed to run it on a GNU C Compiler. Try running the code on an online C compiler, it should work just fine.

How to ignore floating number in scanf("%d")?

If user enters floating number for an integer variable I want to print invalid input. is that possible?
int a;
scanf("%d",&a); // if user enters 4.35 print invalid input
I have tried for characters like this
if(scanf("%d",&a)==1);
else printf("invalid input");
But how to do for floating numbers. If user enters 4.35 it truncates to 4 but I want invalid input.
Since the start of a floating point number with any digits before the decimal point looks like an integer, there is no way to detect this with %d alone.
You might consider reading the whole line with fgets() and then analyzing with sscanf():
int a;
int n;
char line[4096];
if (fgets(line, sizeof(line), stdin) != 0 && sscanf(line, "%d%n", &a, &n) == 1)
...analyze the character at line[n] for validity...
(And yes, I did mean to compare with 1; the %n conversion specifications are not counted in the return value from sscanf() et al.)
One thing that scanf() does which this code does not do is to skip blank lines before the number is entered. If that matters, you have to code a loop to read up to the (non-empty) line, and then parse the non-empty line. You also need to decide how much trailing junk (if any) on the line is tolerated. Are blanks allowed? Tabs? Alpha characters? Punctuation?
You'll have to read it as a double and then check if it is an integer. The best way to check if it is an integer is to use modf, which returns the decimal portion of the double. If there is one you have an error:
double d;
scanf("%lf", &d);
double temp;
if(modf(d, &temp)){
// Handle error for invalid input
}
int a = (int)temp;
This will allow integers or floating point numbers with only 0s after the decimal point such as 54.00000. If you want to consider that as invalid as well, you are better off reading character by character and verifying that each character is between 0 and 9 (ascii 48 to 57).
This can not be done with out reading pass the int to see what stopped the scan.
Classic idiom
char buf[100];
if (fgets(buf, sizeo(buf), stdin) == NULL) {
; // deal with EOF or I/O error
}
int a;
char ch;
if (1 != sscanf(buf, "%d %c", &a, &ch)) {
; // Error: extra non-white space text
}
You can do it using strtol() and strtod() and comparing the end pointers, e.g. this:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char buffer[100];
char * endptr_n;
char * endptr_d;
long n;
double d;
fgets(buffer, 100, stdin);
n = strtol(buffer, &endptr_n, 10);
if ( endptr_n == buffer ) {
fputs("You didn't enter a number.", stderr);
return EXIT_FAILURE;
}
d = strtod(buffer, &endptr_d);
if ( *endptr_d == '\0' || *endptr_d == '\n' ) {
if ( endptr_d == endptr_n ) {
puts("You entered just a plain integer.");
} else {
puts("You entered a floating point number - invalid.");
}
} else {
puts("You entered garbage after the number - invalid.");
}
return EXIT_SUCCESS;
}
outputs:
paul#local:~/src/c$ ./testint
2
You entered just a plain integer.
paul#local:~/src/c$ ./testint
2.3
You entered a floating point number - invalid.
paul#local:~/src/c$ ./testint
3e4
You entered a floating point number - invalid.
paul#local:~/src/c$ ./testint
4e-5
You entered a floating point number - invalid.
paul#local:~/src/c$ ./testint
423captainpicard
You entered garbage after the number - invalid.
paul#local:~/src/c$
It doesn't use scanf(), but that's a good thing, and it avoids the need to manually check the input following the integer you read.
Obviously, if the only thing on the line is the number, then a lot of this becomes unnecessary, since you can just call strtol() and check *endptr_n immediately, but if there may be other stuff on the line this is how you can do it, e.g. if you want to accept an integer followed by anything non-numeric, but not a floating point followed by the same thing, you can just remove the if ( *endptr_d == '\0' || *endptr_d == '\n' ) logic.
EDIT: updated the code to show the check to *endptr.
This one is bit easier:
#include <stdio.h>
int main()
{
int a;
long double b;
scanf("%f",&b);
a = (int) b;
a == b ? printf("%d\n",a) : printf("Invalid input!");
return 0;
}
Input: 4
Output:
4
Input: 4.35
Output:
Invalid input
Here's an easy way:
#include <stdio.h>
int main(int argc, char **argv) {
int d;
printf("Type something: ");
// make sure you read %d and the next one is '\n'
if( scanf("%d", &d) == 1 && getchar() == '\n' ) {
printf("%d\n", d);
}
return 0;
}
.
$ a.exe
Type something: 312312.4214
$ a.exe
Type something: 2312312
2312312
$ a.exe
Type something: 4324.
$
First of all, there is nothing wrong with scanf. When a user enters a float then they actually type in a number dot number. So, code a scanf to detect that data entry.
main()
{
char c1[2];
int num1;
int nr_nums;
nr_nums = scanf("%d%1[.e0123456789]", &num1, &c1);
if (nr_nums == 1) {printf("\ndata = %d", num1);}
if (nr_nums == 2) {printf("\nInvalid");}
}
Modified this code per another possible data entry format of 1. or 3e-1 as suggested by a comment.
This code gets to the basics of your requirement. It accepts Integer data entry and detects when a float is entered.
If you have your number represented as a string (when you have used fgets) you can run a for loop through it and compare each character to '.'.
One other option I can see follows:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char mystring[31];
scanf("%30s[0-9]\n", mystring);
int mynumber = atoi(mystring);
printf("here is your integer: %d", mynumber);
getchar();
getchar();
return 0;
}

Resources