Using character constant in C - c

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*.

Related

Why am I not getting the concatenated string?

I have written this code where I want to add two integers, two doubles and concatenate two strings out of which one of the integer, double and the string is already declared and the other integer, string and double are to be taken by the user. But it seems that the program isn't taking another string as an input.
I have written a similar program where I can take the string from the user using scanf but the same isn't working here.
int main() {
int i = 4;
double d = 4.0;
char s[] = "My college name is ";
// Declare second integer, double, and String variables.
int i2,sum1;
double d2,sum2;
char s2[100];
// Read and save an integer, double, and String to your variables.
scanf("%d",&i2);
scanf("%lf",&d2);
scanf("%[^\n]%*c",&s2);
sum1= i+i2;
sum2= d+d2;
strcat(s,s2);
// Print the sum of both integer variables on a new line.
printf("%d\n",sum1);
printf("%.1lf\n",sum2);
printf("%s",s);
return 0;}
After I made the necessary changes like removing & from s2 and changing s[] to s[200], I still cannot get the concatenated string. I am writing my edited code. Kindly help me with that.
int main() {
int i = 4;
double d = 4.0;
char s[200] = "My college name is ";
// Declare second integer, double, and String variables.
int i2,sum1;
double d2,sum2;
char s2[100];
// Read and save an integer, double, and String to your variables.
scanf("%d",&i2);
scanf("%lf",&d2);
scanf("% [^\n]%*c",s2);
sum1= i+i2;
sum2= d+d2;
strcat(s,s2);
// Print the sum of both integer variables on a new line.
printf("%d\n",sum1);
printf("%.1lf\n",sum2);
printf("%s",s);
return 0;
}
Kindly help me with the bug here.
It's not taking your string input because you use %[^\n]%*c to scan the string. which instuct the program to return after geting a newline as input. And the string got a newline form the buffer after scanning d2, and return with out taking further input.
To get rid of this you need to input a char before taking the input of the string. Change the following lines:
scanf("%lf",&d2);
scanf("%[^\n]%*c",&s2);
To:
scanf("%lf",&d2);
getchar();
scanf("%[^\n]%*c",&s2);
And your code will take the string input properly.
Additionally, you can also do this (taking a extra character input befor string input) by putting a extra space before % sign.
Changing the following line:
scanf("%[^\n]%*c",&s2);
To:
scanf(" %[^\n]%*c",&s2);
Also do the same thing.
You are passing the wrong type of argument to scanf. s2 is an array of chars, so &s2 is a pointer to an array of chars, not a pointer to a char.
(You also ought to have bounds checking to prevent array overflows, add a newline to your final printf, etc. But eliminating the & will make your program compile and run)
Possibly your use of
scanf("%[^\n]%*c",&s2);
As far as I'm aware you can use
scanf("%[^\n]%*c",s2);
or
scanf("%[^\n]%*c",&s2[0]);
As the variable s2 is itself a pointer to the first memory address of the array, using &s2 is just a pointer to a pointer and has no allocated consecutive memory addresses to fill. Hope this helps.
Replace:
scanf("%[^\n]%*c",&s2);
With:
fgetc(stdin);
fgets(s2, 100,stdin);

problems with c pointer strings

:)
I'm trying to beat string pointers in c, so I write this code but I didn't get the result that I expected.
I'm creating a string variable, and I want to pass it to a function that check if the string lenght is bigger than 10.
This is the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
bool is_bigger_than_10(char *);
int main()
{
char *string1 = "";
int i = 0;
printf("Initial string: %s\n",&string1);
printf("Size is: %d\n",strlen(&string1));
printf("Give me one string: ");
scanf("%[^\t\n]s",&string1); //This scan allows me to enter string with spaces
printf("You write: %s\n", &string1);
printf("Size is: %d\n",strlen(&string1));
printf("String character by character:\n");
for(i = 0; i < strlen(&string1) ; i++)
{
printf("%c ",&string1[i]);
}
printf("\nNow let's check if it's bigger than 10\n");
printf("Answer is: %d",is_bigger_than_10(&string1));
return 0;
}
bool is_bigger_than_10(char *textx)
{
printf("%s --> %d > %d\n",&textx, strlen(&textx),10);
if(strlen(&textx) > 10)
{
return true;
}
else
{
return false;
}
}
The expected output should be:
Initial string:
Size is 0:
Give me one string: axel
You write: axel
String character by character:
a x e l
Now let's check if it's bigger than 10
a x e l --> 4 > 10
Answer is: 0
If yoy run that code and enter axel as the input string you will get this:
Initial string: $0#
Size is 3:
Give me one string: axel
You write: axel
String character by character: a b c d e
a x e l
Now let's check if it's bigger than 10
' --> 3 > 10
Answer is: 0
It's kind of weird, could some one help me to correct this code?
There are two things going on here:
First, your char pointer needs to point somewhere. With the line
char *string1 = "";
you create a pointer to a string literal, which you can't write to. (Obviously you can, given your output, but you just got lucky on a system that allows it.) Create a character buffer instead:
char string1[200] = "";
and ideally enforce the constant buffer limit when you read the string.
Second, you don't need all these &s. The & is not a magic marker that you have to prepend to all your arguments.
The & takes the address of a variable and passes it as a pointer. You need that when the called function needs to change the variable via the pointer. Printing doesn't need to change anything, so unless you want to print the address of a variable with %p, you shouldn't pass addresses. (In the special case of your program, you can just remove all ampersands with search and replace.)
When scanning, you need to change variables if you convert input to numbers or if you scan a char. The exception is when you scan strings with %sor %[...]: Here, you pass a char buffer (as a pointer to its first elements) and the function then fills that buffer.
The problem with scanf and printf is that the arguments after the format string are variadic, which means they will accept any arguments without type checking. The good thing is that most compilers can tell whether a format string matches the arguments and will issue warnings, it you enable them. Do yourself a favour and do that.
(Warnings will also tell you that you have type mismatches in functions where the type of the argument is known, such as your is_bigger_than_10.)

C dynamic data specifiers

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

Append to C String Based on User Input

I would like to receive an integer x via user input, and return a string with length x in '#'s.
i.e.
x = 4
⇒ "####"
Is a simple solution possible, along the lines of:
printf( "%c * x = %c", hash, x, hash*x);
Currently, my online findings have me creating an iterative program:
#include <stdio.h>
#include <string.h>
//function creates xhash with width '#' characters
void append( char* xhash, char hash, int x )
{
int i = 0;
for ( i = 0; i < x; i++ ) { xhash[i] = hash; }
xhash[x] = '\0';
}
int main ( void )
{
int x = 0;
scanf( "%d", &x );
char xhash[250] = "";
char hash = "#";
append( xhash, hash, x );
printf( "%c", xhash );
return 0;
}
And this gives me a strange design: ▒
I find C strings very confusing, coming from Python where I would use
str.append(i)
or
str = "#" * x
C does not have a full-fledged string data type. "C strings" are just contiguous sequences if char values, terminated by a character with value 0 (which can be spelled '\0').
Very important to your question, though, is that (1) char is an integer data type, (2) different delimiters are used for string literals than for (single-)char literals, and (3) string literals evaluate to pointers to the first character of a C string.
Thus, this ...
char hash = "#";
... attempts to store a pointer in hash, probably resulting in the last byte of the pointer value. Instead, you want this:
char hash = '#';
Moreover, to print a C string via one of the printf()-family functions, you want to use edit descriptor %s:
printf("%s", xhash);
Descriptor %c is for outputting a single character.
A string in C is just an array of bytes followed by a zero byte. That is all that they are.
For a function that creates a string you have two options. You can have the caller pass in a pointer to an array (and the array size, if you're smart) and the function fills it in. The second option is to malloc inside your function and return the pointer to the caller.
Another thing to remember is the standard C library. Your append function is essentially memset followed by setting a zero at the end. You should just call memset instead of doing your own loop.
And I think you are getting weird output because the printf format for a string is %s not %c. The %c format is for a single character.
Finally if you are unfamiliar with C programming you should be compiling will all warnings turned on. The compiler warnings would have told you about the bad printf format string and the invalid char assignment.

How to use fprintf with a dynamically allocated unsigned char* array in C

I'm trying to write a unsigned char* array to a file.
A minimal working example of the code that I've tried so far is (assume fp is correctly initialised):
unsigned char* x; int i; int j; int sizeOfx;
for (i=0; i<n; i++) {
x = // getter function with parameter i
sizeOfx = // getter function that returns the number of elements in x
for (j=0; j<sizeOfx; j++) {
fprintf(fp,"%s",x[j]);
}
}
i.e. I'm going through the char array one element at a time and writing it to the file.
However, I get the error
format ‘%s’ expects argument of type ‘char*’, but argument 3 has type ‘int’ [-Wformat]
How can I fix this?
Thank you very much in advance!
%s is used to print a string, so you would need to change x[j] to x to 'fix' your error.
As you really seem to want to write each char separately, you need to think how you want to store the 'elements' (characters of the string).
You can use %c to store their value as an ASCII value in the file (which is basically identical when using %s and x, unless you want to write more/less than the complete string).
Or you can store the 'element values' as integers, ie textual values using the characters 0-9, using %d. Or maybe hexadecimal using %x using the characters 0-9 and a-f.
So it is up to you how you want to store the 'elements' of x.
Try %c (for character printing) instead of %s.
Alternatively you could write the print line as follows:
fprintf(fp,"%s",(char*)x[j]);
which statically casts that pointer at x[j] back to a string (essentially), then if the string coming into that loop were "abcdef", then the output would be as follows:
"abcdefbcdefcdefdefeff"
This is where c is completely open to do what you want to do.

Resources