scanf() value ignored after reading a char - scanf

Got stuck on an problem getting more familiar with C(++) on Hackerrank. Using scanf() I want to read a line with a bunch of different values.
The issue is that the value after char is ignored. Read solutions to this was to add a space before the char, but I've tried running a scanf() on a seperate line per value, and only keeping the space infront of the char but still the problem persisted.
The lesson to be learned seems to be using scanf() and not any other type of input method. So no reading with cin or fscanf(). And reason for this being one can read all kinds of values on the same line. So I don't want to make more than this one line for reading the input either.
#include <iostream>
#include <cstdio>
using namespace std;
int main() {
int i;
long l;
long long ll;
char c;
float f;
double d;
/** Read "3 444 12345678912345 a 334.23 14049.30493" from stdin */
scanf("%i %ld %lld %c %f %lf", &i, &l, &ll, &c, &f, &d);
printf("%d\n", i); // 3, as expected
printf("%ld\n", l); // 444 also as expected
printf("%lld\n", ll); // 12345678912345 ...
printf("%c\n", c); // 'a'
printf("%f\n", d); // 14049.30493 ?? It should be: 334.23
printf("%lf\n", d); // 14049.30493 but this time as it should be.
return 0;
}

scanf("%i %ld %lld %c %f %lf", &i, &l, &ll, &c, &f, &d);
^
!F! D
printf("%d\n", i);
printf("%ld\n", l);
printf("%lld\n", ll);
printf("%c\n", c);
printf("%f\n", d); // < D!
printf("%lf\n", d); // < D!
You are printing the d variable twice and never f.

Related

How can I convert the input operator (+,-) to math in C

Assume that the given input are 5,+,5 in C.
ex)
5
+
5
And I would like to get the answer 10.
I thought code like the below.
#include
using namespace std;
int main(){
char a,b,symbol;
cin >> a >> symbol >> b;
printf("%d", (a-'0') symbol (b-'0'));
return 0;
}
Expected value is 10. However, I got an error in symbol
How would I get the solution?
There are multiple things that I noticed:
First, you are printing integer, but a and b are both chars.
Knowing that there are only a few symbols that you can use, maybe a switch case would be more appropriate?
int main(){
int a, b;
char symbol;
switch(symbol){
case('-'): print("%d", a - b);
case('+'): print("%d", a + b);
case('*'): print("%d", a * b);
case('/'): print("%d", a / b);
case('%'): print("%d", a % b);
default : print("Not a known symbol");
}
Second: Why are you substracting a from the character 0?

Fread/fwrite unexpected behavior

I have created a file 'meta.dat' in my current directory and want the code below to give me this output
The character B
Number of items read 1
int main() {
FILE* fp = fopen("meta.dat", "wb");
char j = 'B';
fwrite(&j, sizeof(j), 1, fp);
fclose(fp);
FILE* fp1 = fopen("meta.dat", "rb");
char i = '\0';
int n = fread(&i, sizeof(i), 1, fp1);
printf("The character %c\n", &i);
printf("Number of items read %d\n", &n);
}
However what I get is this output in my console (I use Windows):
The character &
Number of items read 6422304
What's wrong with the code? And what's happening behind the scenes, why am I seeing this strange output?

strncpy functions produces wrong file names

I am new in C and writing a code to help my data analysis. Part of it opens predetermined files.
This piece of code is giving me problems and I cannot understand why.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXLOGGERS 26
// Declare the input files
char inputfile[];
char inputfile_hum[MAXLOGGERS][8];
// Declare the output files
char newfile[];
char newfile_hum[MAXLOGGERS][8];
int main()
{
int n = 2;
while (n > MAXLOGGERS)
{
printf("n error, n must be < %d: ", MAXLOGGERS);
scanf("%d", &n);
}
// Initialize the input and output file names
strncpy(inputfile_hum[1], "Ahum.csv", 8);
strncpy(inputfile_hum[2], "Bhum.csv", 8);
strncpy(newfile_hum[1], "Ahum.txt", 8);
strncpy(newfile_hum[2], "Bhum.txt", 8);
for (int i = 1; i < n + 1; i++)
{
strncpy(inputfile, inputfile_hum[i], 8);
FILE* file1 = fopen(inputfile, "r");
// Safety check
while (file1 == NULL)
{
printf("\nError: %s == NULL\n", inputfile);
printf("\nPress enter to exit:");
getchar();
return 0;
}
strncpy(newfile, newfile_hum[i], 8);
FILE* file2 = fopen(newfile, "w");
// Safety check
if (file2 == NULL)
{
printf("Error: file2 == NULL\n");
getchar();
return 0;
}
for (int c = fgetc(file1); c != EOF; c = fgetc(file1))
{
fprintf(file2, "%c", c);
}
fclose(file1);
fclose(file2);
}
// system("Ahum.txt");
// system("Bhum.txt");
}
This code produces two files but instead of the names:
Ahum.txt
Bhum.txt
the files are named:
Ahum.txtv
Bhum.txtv
The reason I am using strncpy in the for loop is because n will actually be inputted by the user later.
I see at least three problems here.
The first problem is that your character array is too small for your strings.
"ahum.txt", etc. will need to take nine characters. Eight for the actual text plus one more for the null terminating character.
The second problem is that you have declared the character arrays "newfile" and "inputfile" as empty arrays. These also need to be a number able to contain the strings (at least 9).
You're lucky to have not had a crash from overwriting memory out the program space.
The third and final problem is your use of strcpy().
strncpy(dest, src, n) will copy n characters from src to dest, but it won't copy final null terminator character if n is equal or less than size of the src string.
From strncpy() manpage: https://linux.die.net/man/3/strncpy
The strncpy() function ... at most n bytes of src are copied.
Warning: If there is no null byte among the first n bytes of src,
the string placed in dest will not be null-terminated.
Normally what you would want to do is have "n" be the size of the destination buffer minus 1 to allow for the null character.
For example:
strncpy(dest, src, sizeof(dest) - 1); // assuming dest is char array
There are a couple of problems with your code.
inputfile_hum, newfile_hum, need to be to be one char bigger for the trailing '\0' on strings.
char inputfile_hum[MAXLOGGERS][9];
...
char newfile_hum[MAXLOGGERS][9];
strncpy expects the first argument to be a char * region big enough to hold the expected results, so inputfile[] and outputfile[] need to be declared:
char inputfile[9];
char outputfile[9];

snprintf() return value when size=0

Thanks first for your time spent here. I have a question with snprintf() when size=0, with code below:
#include <stdio.h>
#include <stdlib.h>
int main(int ac, char **av)
{
char *str;
int len;
len = snprintf(NULL, 0, "%s %d", *av, ac);
printf("this string has length %d\n", len);
if (!(str = malloc((len + 1) * sizeof(char))))
return EXIT_FAILURE;
len = snprintf(str, len + 1, "%s %d", *av, ac);
printf("%s %d\n", str, len);
free(str);
return EXIT_SUCCESS;
}
when I run:
momo#xue5:~/TestCode$ ./Test_snprintf
The result is:
this string has length 17
./Test_snprintf 1 17
What confuses me is in the code, the size to be written is 0, why displayed 17?
What did I miss?
Thanks~~
The solution can be found in the man page under Return value;
The functions snprintf() and vsnprintf() do not write more than size bytes (including the terminating null byte ('\0')). If the output was truncated due to this limit then the return value is the number of characters (excluding the terminating null byte) which would have been written to the final string if enough space had been available.
This is so that you can do exactly what you do, a "trial print" to get the correct length, then allocate the buffer dynamically to get the whole output when you snprintf again to the allocated buffer.

reading files using fgetc

I have a question about using fgetc to count characters in a specified file.
How do you use it when you have to count character types separately? Like for example I only want to count the number of lowercase characters only, or number of spaces, or punctuations, etc? Can someone show a brief example? Thank you
I tried to do this program that would hopefully count the total number of characters, how do you squeeze in though the number of the separate character types? I'm not exactly sure if this program is correct
#include <stdio.h>
int main (void)
{
//Local declarations
int a;
int count = 0;
FILE* fp;
//Statements
if (!(fp = fopen("piFile.c", "r")))
{
printf("Error opening file.\n");
return (1);
}//if open error
while ((a = fgetc (fp)) != EOF)
{
if (a != '\n')
count++;
printf("Number of characters: %d \n", count);
else
printf("There are no characters to count.\n");
}
fclose(fp);
return 0;
}
Read up on these functions:
int isalnum(int c);
int isalpha(int c);
int isascii(int c);
int isblank(int c);
int iscntrl(int c);
int isdigit(int c);
int isgraph(int c);
int islower(int c);
int isprint(int c);
int ispunct(int c);
int isspace(int c);
int isupper(int c);
int isxdigit(int c);
and you'll see right away how to do it.
In your while, you can use if statements for each character you want to check.
if(isalnum(a){
counta++;
}
else if(isalpha(a)){
countb++;
}
else if(isascii(a)){
countc++;
}