I want to write something like the following code, but I failed.
I want to assign dynamic number of chars from array y to x. This number will be defined later. Here is a simple example of what I mean.
#include<stdio.h>
int main()
{
int x=0;
char y[]={'5','4'};
int z=1;
sscanf(y,"%zi",&x);
printf("%i",x); //Each time value of x=0
sscanf(y,"%1i",&x); //I want to make this 1 dynamic "int z"
printf("%i",x); //Here x value =54.
return 0;
}
Succinctly, you can't do what you want directly.
With printf(), you can use this, where all three variables are of type int and the widths will be read from x and y:
printf("%*.*d", x, y, z);
However, the scanf() family of functions provides nothing analogous. A * means 'assignment suppression' in scanf(). Note that in C99 and beyond, %zi tells scanf() that the type of the pointer argument is size_t *. This probably accounts for why you got 0 as a result; sscanf() was writing out of bounds for the variable you passed to it.
Your best bet is to use snprintf() to create the format string you want used by scanf().
int x;
char y[] = { '5', '4' };
int z = 1;
char format[16];
snprintf(format, sizeof(format), "%%%di", z);
if (sscanf(y, format, &x) != 1)
…handle error…
printf("%d\n", x); // Will print 5
Note that if z is 1 or 2, this works OK; if z is larger, then y is not a null-terminated string and you run into undefined behaviour. If z is zero or negative, you run into problems too.
If you see , you declared and initialized array like this -
char y[]={'5','4'};
y is not a string because it is not terminated using '\0' , so you need to explicitly add nul terminater . As sscanf will take a c-style string as first argument.
char y[]={'5','4','\0'}; // or char y[]="54";
Working demo
Related
I'm fairly new to all of this and I somehow can't seem to find a solution. Although I have no syntax errors, the program doesn't work as its supposed to.
I want the users to input two firmnames [int read ()] which get saved under the char arrays x and y. From there I want to compare them both if they are equal or not [int equal()]. After that, if they are equal, I want to print out accordingly[int stringconcatenate()]
I want **read() ; equal() ; stringconcatenate() to be connected with the main program and work accordingly.
I'm trying to take the entered "firmnames" and then save them under the array name x and y. (which doesn't work as it should).. Am I missing something?
this is what I get if I enter "test" for both firmnames:
Please type in Firmname 1: test
Please type in Firmname 2: test
Strings are unequal.
a & ³■a are different.
Any tips are very much appreciated.
Btw, I'm not allowed to use strcmp, hence my unorthodox code.
#include <stdio.h>
#include <ctype.h>
int read (){
char x[50];
char y[50];
printf("Please type in Firmname 1:\t");
scanf("%s", &x);
printf("Please type in Firmname 2:\t");
scanf("%s", &y);
}
int Equal (char x[], char y[]){
char *p1,*p2;
int f = 0;
p1=x;
p2=y;
while (*p1!= '\0' || *p2!='\0'){
if(*p1 != *p2){
f=1;
break;
}
p1++;
p2++;
}
if (f==0)
printf("\nStrings are equal.\n");
else
printf("Strings are unequal.");
}
int stringconcatenate(char x[], char y[]){
char *p1,*p2;
p1=x;
p2=y;
if (*p1==*p2){
printf ("\n %s is the only one.", x);
}
else
printf ("\n %s & %s are different.", x, y);
return 0;
}
int main(){
char s1[50], s2[50];
printf("Program Compare\n\n");
read ();
Equal (s1, s2);
stringconcatenate(s1, s2);
return 0;
}
The basic problem is your read function which is wrong.
In your original code, x and y are local variables which exist only during the execution of the read function; afterwards the are discarded and cannot be used any more. Furthermore there is no reason why x and y would be magically copied to s1and s2.
This is the corrected version of read:
int read(char x[50], char y[50]) { //
printf("Please type in Firmname 1:\t");
scanf("%s", x); // use x and not &x, x is already an address
printf("Please type in Firmname 2:\t");
scanf("%s", y); //
}
and call it like this from main:
read(s1, s2);
There are more problems in your code:
Equal and read are int function, but they don't return anything, so they should rather be void functions.
Rather than displaying if the strings are equal or not, Equal should return e.g. 1 if the strings are equal and 0 if they are not and the display of the result should be done in main. This is not a programming error but rather a design error.
your strconcatenate function doesn't even attempt to do a string concatenation. I'm not sure what you're trying to achieve with this code.
Note, I assume this is an assignment, so I will only include some pointers (no puns intended) so that you can correct the mistakes by yourself.
Ok, let's address problems function by function.
int read (){
char x[50];
char y[50];
printf("Please type in Firmname 1:\t");
scanf("%s", &x);
printf("Please type in Firmname 2:\t");
scanf("%s", &y);
}
This function simply reads two strings from standard input (stdin from now on) and then it throws them away. Neither x nor y are in some ways returned to the main function, that means that, when you call read in the main, and I assume you expect s1 and s2 to have, respectively, the value of x and y, s1 and s2 do not change. What you can do to address this problem is to pass a pointer to s1 and s2 to the read function. In fact, in the C language arrays used in expression have the same value of the pointer to their first element (for instance, if I use s1 in an expression, it gets converted to the pointer to the first element of s1). That being said, please pass |(the pointers of) s1 and s2 to the read function and use scanf on them. Another problem with this function is that it says that it returns an int, but it fact it returns nothing. Please change the function to address this problem.
(There is another problem with the read function that is "what if I input, for instance, the entire GPL license? The program will not be happy and it might crash. Please have a look at cppreference).
The second function I see is this:
int Equal (char x[], char y[]){
char *p1,*p2;
int f = 0;
p1=x;
p2=y;
while (*p1!= '\0' || *p2!='\0'){
if(*p1 != *p2){
f=1;
break;
}
p1++;
p2++;
}
if (f==0)
printf("\nStrings are equal.\n");
else
printf("Strings are unequal.");
}
Please, don't use general purpose functions like this to print to standard output. Make equal return a value (for instance 0 if the strings are equal, 1 otherwise).
The while loop condition is wrong: what you're saying is that "if *p1 is not '\0' OR *p2 is not '\0', then go forward with the loop. If one is '\0' but the other is not, the loop will go forward.
I can't figure out what you want to achieve with the stringconcatenate function. Please explain.
I trying to use EOF for user input in a function and also modify the array accordingly, so in the main function it'll be that value. I've tried searching with Google and reading over people's answers, but I still can't get it to work..
void Get_Data(double data[], double original[], int length)
{
int count = 0;
double value = 0;
printf("Enter data and Ctrl + D when you're done(Ctrl + Z for Windows): \n");
while (scanf("%f", &value) != EOF)
{
data[count] = value;
original[count] = data[count];
count++;
}
printf("%f\n", data[1]);
}
int main()
{
int i;
double sum, original[4] = {0}, datas[4] = {0};
Get_Data(datas, original, 4); // I'm just trying to get this to work
system("pause");
return 0;
}
I read about passing by reference in C using * in the parameters, but I didn't get the right result.
To scan a double value, you need to use %lf format specifier.
From C11, chapter §7.21.6.2,
l (ell) Specifies that a following d, i, o, u, x, X, or n conversion specifier applies
to an argument with type pointer to long int or unsigned long
int; that a following a, A, e, E, f, F, g, or G conversion specifier applies to
an argument with type pointer to double; [....]
That said,
as you're rightly passing the length, make use of it inside your function to limit the count (index) to avoid overrunning the allocated memory.
You should also check for the success of scanf() (by checking the returned value against the number of items supposed to be scanned). Only checking aginst EOF foes not suffice, scanf() can also return 0 in case of matching failure which needs to be handled, too.
Change while (scanf("%f", &value) != EOF) to while (scanf("%lf", &value) == 1).
Firstly, to check whether a input process succeeds, you shouldn't use scanf("...", ...) != EOF. Think about it: What if a user inputs a character? Then scanf() will return 0 after having a matching failure, and 0 != EOF.
Secondly, to scan a variable has the type of double, you have to use a "%lf". You may ask: Why? I can print both float and double by using a "%f"!
Well, that is because usually sizeof (float) != sizeof (double). Let's say sizeof (float) == 4 and sizeof (double) == 8:
In a scanf() statement, the program have to know the length of memory block to write to. If there is a "%f", and 0x12345678 is passed as the corresponding address, 0x12345678 to 0x1234567C are filled, while when there is a "%lf", and 0x12345678 is passed as the address, memory from 0x12345678 to 0x12345680 are filled.
Since printf() has variadic parameters, float variables are implicitly converted to double, then passed. It's obvious that convert a float to double doesn't cause any lost of information, so everything is OK.
To sum up, the point is that floats are automatically promoted to doubles, but float *s are not converted to double *.
I'm trying to write a program and I'm having some trouble assigning a certain word to a variable. the part that is giving me problems is this simple bit of code:
char x;
if (friction > fN || friction < -fN) {
x = 'false';
printf("\%s\n", x);
}
else {
x = 'true';
printf("\n%s\n", x);
}
fprintf(Output,"%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf, %s\n", theta, theta_rad, V, Fa, Uc, Vc, moment, fN, friction, x);
Essentially I'm just trying to output whatever the x "value" is and include it in my file.
I'm getting the following two warnings, all in relation to the lines x = 'false' and x = 'true' and how I am declaring my char x.
warning: character constant too long for its type
warning: overflow in implicit constant conversion
warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘int’
Note: the rest of the arguments in the fprintf are printing fine, the issue is only in how I'm declaring the char. In the end, it is not printing the x 'value' at all...
Thank you in advance and I appreciate any help!
char store only one character. You need to declare an array of characters (more commonly known as string) and use the string.h functions (namely, strcpy) to copy and store your strings.
Also note that strings are enclosed in double quotes, not single quotes.
Having put #include <string.h> with your headers:
char x[255];
if (friction > fN || friction < -fN) {
strcpy(x, "false");
printf("\%s\n", x);
}
else {
strcpy(x, "true");
printf("\n%s\n", x);
}
fprintf(Output,"%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf, %s\n", theta, theta_rad, V, Fa, Uc, Vc, moment, fN, friction, x);
Of course, you might just want to print the "true" and "false" strings directly, if you're not using the x variable later.
The problem you have with your code is that you declared x as a char. A char is a type that can store only 1 character. So, if you want to store more than 1 character, you need to use what is called a string. A string can be declared as a char vector. For example, char str[20] declare a string of 20 characters. However, in your case is better to use (note the third warning you get from your compiler) a pointer to a constant char, defined with char* str="string content". Please, take note the use of double quotes (") istead of the single quote (').The difference between them is that a single quote is used to initialize a char, for example char c='a'. When you declare a string, you have to use the double quotes, for example char *str="hello world!", or char str[]="hello world!". When you declare a string with double quotes, a special character, called string termintor ('\0', note that this is a single character so you use the single quote around it) is added at the end of the string.
Here is an example of your code:
char* x; // x is declared as a constant string
if (friction > fN || friction < -fN) {
x = "false";
printf("\%s\n", x);
}
else {
x = "true";
printf("\n%s\n", x);
}
chars are for only a single character. You will need to use strings for multiple characters.
char * x = "false"; /*double quotes*/
printf("%s\n", x);
That said, if just want to represent true and false its better to use the integers 1 and 0, respectively, since this way you can pass them to if statements and other conditionals.
As other users pointed out, char can only store one character (as the name says). An alternative code for what you are trying to do would be:
if (friction > fN || friction < -fN) {
printf("false\n");
}
else {
printf("true\n");
}
The char type is used to store a single character but you are trying to define constants that are of several characters. If you want a sequence of characters then use quotes (") and const char*.
the code is like this:
char c;
scanf("%d", &c);
inputting 3...
My guess is that when 3 is inputted, it is as type int;
and then type-demoted to char and assigned to c;
I print the value of c in specifier %d yielding 3, seems to be as expected;
but printing the value of c with specifier %c yields --a blank-- on the terminal;this is one question...(1);
to test more I furthermore declare a variable ch with type char and initialized it like this:
char ch = 1;
and the test is like this:
(i&j)? printf("yes") : printf("no");
and the result is "no"
I print out the value of i&j, and it is 0
but 1&3 should be 1? this is another question....(2);
my question is (1) and (2)
You're actually invoking undefined behavior doing that.
By using the format string %d, you're telling scanf to expect an int* as a parameter and you're passing it a pointer to a single character. Remember that scanf has no further type information on what you're passing it than what you're putting in the format string.
This will result in scanf attempting to write an int sized value to memory at an address that points to a char sized reservation, potentially (and for most architectures) writing out of bounds.
After invoking UB, all bets are off on your further calculations.
Suppose that scanf() were not a varargs-function, but a plain ordinary function taking a pointer-to-int as the 2nd argument:
int noscanf(char *format, int *ptr)
{
*ptr = 42;
return 1;
}
int main(void)
{
char ch;
int rc;
// This should *at least* give a warning ...
rc = noscanf("Haha!" , &ch);
return 0;
}
Now, scanf() is a varargs function. The only way for scanf() to determine the type of the (pointer) arguments is by inspecting the format string. And a %d means : the next argument is supposed to be a pointer to int. So scanf can happily write sizeof(int) bytes to *ptr.
I can't see a variable jthere. So i&j will be 0. And yes, if i == 1 and j == 3 then i & j == 1.
(i&j)? printf("yes") : printf("no");
statement gives the output yes,for i=1 and j=3.
And for (1) question ASCII 3 is for STX char which is not printable.
Hi I have a text file which contains the below data
ABC00011234567
XYZ00021234567
To get the data, i have defined a structure
typedef struct data {
char x[3];
char y[4];
char z[7];
} key;
in the program what I do is read each line and assign it to the structure
unsigned char buf[1024];
fgets(buf,sizeof(buf),fptr);
key *k=(key*)buf;
int y = atoi(k->y)
printf( "y=%d\n",y);`
I'm getting the output as
y=1123456
y=2123456
the output Im expecting is
y=1
y=2
should I assume, atoi takes the pointer of the string and iterates till EOF is encountered?
what should I do to get the values 1 and 2?
atoi takes a nul-terminated string. You'll have to add your own terminators to your key members if you want to limit the length of data atoi parses
You should assume that atoi() keeps going until it reaches the end of the string or an invalid character. For example, for the string `"123zzz" it'd return 123.
You should either terminate your strings (put a zero at the end of them) and stop using atoi() (e.g. use strtol() instead); or write your own conversion that doesn't need a terminated string.
Note: (in general) atoi() should never be used for anything other than writing a compiler, because it does things that don't make sense to normal people (e.g. "0129" is 10 and not 129 because it decides the number is octal and the 9 isn't a valid digit for octal).
The atoi function expects a null-terminated string; you are passing a portion of the char array that has its termination past the boundaries of key::y, so atoi interprets the entire value as a number. If you would like to stick to your "cookie cutter" method of parsing the key, you need to make a copy, and pass it to atoi:
char temp[5];
memcpy(temp, k->y, 4);
temp[4] = '\0';
int y = atoi(temp);
However, I think that using fscanf is a better choice:
char x[4];
int y, z;
fscanf(fptr, "%3s%4d%7d", x, &y, &z);
printf("%s %d %d", x, y, z);
atoi() assumes a zero terminated string. In your case, the string will not be zero-terminated, and thus the data in z is read by atoi after y has been read.
To read just the 4 digits, you can use sscanf:
sscanf(k->y,"%4d",&y);