i noticed that variable value have been changed after strcpy function,i don't know how and why this is happening.
this is my code:
#include <stdio.h>
#include <string.h>
int main()
{
int b = true;
char ch[3];
strcpy(ch,"int");
printf("b value is:%d\n",b);
return 0;
}
I even use a temporary integer variable. it's very strange , in this case, the b value is correct after strcpy but the temp is changed to 0, note that it's just happened when assigning 1 value to b and temp variables.
this is the second code
#include <stdio.h>
#include <string.h>
int main()
{
int b = true;
int tmp=b;
char ch[3];
strcpy(ch,"int");
printf("b value is:%d\n",b);
return 0;
}
strcpy(ch,"int");
is equivalent to
ch[0] = 'i';
ch[1] = 'n';
ch[2] = 't';
ch[3] = 0;
Seeing as ch only has three elements (ch[0]..ch[2]), this invokes undefined behaviour.
Firstly, you need to use number (0,1) in your boolean variables. If you want to use boolean in C as you use them in c++, you have to include stdbool.h library.
Concerning strcpy(dest, src) function, it copies the src string to dest and return à pointer to the copied string.
In reality the size of "int" is not 3 but 4 bytes. String always ends with '\0' character.
In other words :
If you don't understand, try to analyze this code :
#include <stdio.h>
#include <string.h>
int main()
{
int b = 1;
char ch[4];
strcpy(ch,"int");
printf("b value is:%d\n",b);
return 0;
}
I used online compiler and selected "C++" and the error is not happening.
but when I selected C++17 I got this warning "
input
main.cpp:9:12: warning: ‘void __builtin_memcpy(void*, const void*, long unsigned int)’ writing 4 bytes into a region of size 3 ov
w=] "*
as #PaulMcKenzie mentioned this is buffer overflow case.
Related
I'm trying to acquaint myself with the atoi function, so I wrote a basic programme using it, but I'm having some problems:
#include <stdio.h>
#include <cs50.h>
#include <stdlib.h>
int main(void)
{
string s = get_string("String:");
int i = get_int("Integer:");
int a = atoi(s[1]);
int j = i + a;
printf("%i\n", j);
}
When I try to compile it, I get the error message "incompatible integer to pointer conversion passing 'char' to parameter of type 'const char *'; take the address with & [-Werror,-Wint-conversion]". This seems to suggest that it wants something to do with a char, but from what I've read, I was under the impression that atoi was used with strings. If someone could explain where I'm going wrong, I'd be very thankful
You're passing a char(assuming string is a typedef for char*) by indexing the string and it wants you to pass a char*. So just pass the full string:
#include <stdio.h>
#include <cs50.h>
#include <stdlib.h>
int main(void)
{
string s = get_string("String:");
int i = get_int("Integer:");
int a = atoi(s);
int j = i + a;
printf("%i\n", j);
}
here is the syntax for atoi()
int atoi(const char *nptr);
Notice the parameter is a pointer, not a single character.
However, the posted code has:
int a = atoi(s[1]);
which is a single character, not a pointer
suggest:
int a = atoi( s );
Also, the function: atoi() has no facility to let the program know when an error occurred. Suggest using the strtol() function which does have a facility to indicate when an error occurred
This question already has answers here:
How do I properly compare strings in C?
(10 answers)
Closed 2 years ago.
So I am trying to create a little joke with C and I don´t know what I am doing wrong. I see the Error "error: result of comparison against a string literal is unspecified" and do not know how to fix it, can someone help.
#include<stdio.h>
#include<cs50.h>
int main(void){
string a = get_string("ENTER YOUR NAME FOR READING\n");
if (a == "david")
;
{
printf("...");
}
}
Your code has three issues:
1.
if (a == "david")
a decays to a pointer to the first element of array a.
"david" is a string literal.
With the if Statement, you attempt to compare the address of the array a by the address of the string literal "david". String comparison dies not work that way in C.
Use strcmp() - header string.h to compare strings.
strcmp() returns 0 if the strings are equal. To make the if condition turn true you need to use ! negation operator.
2.
There is a misplaced ; between the if condition and if body. Remove it.
3.
The use of cs50.h is deprecated. If you are not required to use it explicitly, leave your hands off from it.
#include <stdio.h>
#include <string.h>
int main (void) {
char a[20];
printf("ENTER YOUR NAME FOR READING:\n");
if (!fgets(a, sizeof a, stdin))
{
fputs("Failure at input", stderr);
// further Error routine.
}
a[strcspn(a, "\n")] = 0;
if (!strcmp(a,"david"))
{
printf("...");
}
}
You cannot compare two strings in c using a comparison operator.
Try using
strcmp(const char* one, const char* two)
That is, in your case
use
#include<stdio.h>
#include<cs50.h>
int main(void){
char[] a = get_string("ENTER YOUR NAME FOR READING\n");
char[] b = "david";
if (!strcmp(a,"david"))
{
printf("...");
}
}
Also, Strings in c are not declared as strings. They are declared as char arrays
Comparing two char pointers like this char *a, *b; a == b; is accepted by the compiler, but if you are using such a syntax to compare the string values, then you may not get the results you are expecting. Some times it may evaluate to true or sometimes to false. The reason is, the program checks whether a and b are pointing to the same address, and not for if they have the same string value. Consider the program below.
#include <stdio.h>
int main()
{
char* a = "test";
char* b;
if ((b="test") == a)
printf("Impossible\n");
else
printf("Thought so\n");
printf("%p %p\n", a, b);
return 0;
}
OUTPUT
Impossible
0x55b6bd52d004 0x55b6bd52d004
As you see from the output, the if block is evaluated to true. The reason is also in the output; a and b are pointing to a similar address. Why?
It comes from the string-pooling, one of the compiler optimization. Even though a and b are initialized at different points in the program, as they are referring to the same string constant, the string constant is initialized only once by the compiler.
Here is the objdump of the executable.
$ objdump -s -j .rodata
a.out: file format elf64-x86-64
Contents of section .rodata:
2000 01000200 74657374 00496d70 6f737369 ....test.Impossi
2010 626c6500 54686f75 67687420 736f0025 ble.Thought so.%
2020 70202570 0a00 p %p..
test is initialized only once. For a quick check, consider this program's output and its objdump .
#include <stdio.h>
int main()
{
char* a = "test";
char* b;
if ((b="test1") == a)
printf("Impossible\n");
else
printf("Thought so\n");
printf("%p %p\n", a, b);
return 0;
}
OUTPUT
Thought so
0x557a96aa9004 0x557a96aa9009
objdump
$ objdump -s -j .rodata a.out
a.out: file format elf64-x86-64
Contents of section .rodata:
2000 01000200 74657374 00746573 74310049 ....test.test1.I
2010 6d706f73 7369626c 65005468 6f756768 mpossible.Though
2020 7420736f 00257020 25700a00 t so.%p %p..
It is evident from the output that a and bare pointing to different locations, and both are having different string values that are initialized by the compiler separately. So, if a and b are having similar string values, does a==b always evaluate to true? Consider the below program.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char* a = malloc(sizeof(char) * 5);
strcpy(a, "test");
char* b;
if ((b="test") == a)
printf("Impossible\n");
else
printf("Thought so\n");
printf("%p %p\n", a, b);
return 0;
}
OUTPUT
Thought so
0x5607d9938260 0x5607d91fb004
Even though the a and b are having the same string values, if evaluate to false. Why? The address a is pointing, which is created by malloc() belongs to the heap section of the executable, whereas the address b is pointing belongs to the data section of the executable, and they are indeed different.
So what should we do to compare the string values?
Well, it is straight forward, there are already library functions which can perform this task. You can use them withstring.h. Consider the below code.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char* a = malloc(sizeof(char) * 5);
strcpy(a, "test");
char* b = "test";
char* c;
if (strcmp((c="test"), a) == 0)
printf("Impossible\n");
else
printf("Thought so\n");
if (strcmp(b, a) == 0)
printf("Impossible\n");
else
printf("Thought so\n");
if (strcmp(b, c) == 0)
printf("Impossible\n");
else
printf("Thought so\n");
printf("%p %p %p\n", a, b, c);
return 0;
}
OUTPUT
Impossible
Impossible
Impossible
0x556debf41260 0x556deac28004 0x556deac28004
Irrespective of where a, b and c are pointing if they all are having the same string values, then strcmp() returns 0.
I've looked around everywhere and tried pretty much everything suggested and can't get anything to work.
this is my code:
#include <stdio.h>
#include <string.h>
#include <math.h>
int main(){
float a;
char *nums[3];
char str[5];
printf("Please enter a,b,c:");
scanf("%s",str);
int i=0;
char *p;
p = strtok (str,",");
while (p != NULL)
{
nums[i++] = p;
p = strtok (NULL, ",");
}
a=atof(nums[0]);
printf("%s\n",nums[0]);
printf("%f\n",a);
return 0;
}
the math.h is for something later on after I figure this out. So if I entered "1,2,3" into this program, my print statements would show me "1" and then "0.000", this is obviously just there for me to test things out but why the does my value just disappear after trying to convert to a float? I need that value of 1 to do math with later in my program but I can't get that char pointer value no matter what I try, I can only seem to print it, but it screws up as soon as I try to convert it into a type I can use.
Two issues:
You nums and str arrays are too short. nums should have a size of at least 3, and str should be at least 6 ("1,2,3" plus null byte), probably more for larger numbers.
So change those to:
char *nums[3];
char str[20];
Second, you don't #include <stdlib.h>, which contains the declaration of atof. Without a declaration, it is assumed to return an int.
Fix the array sizes, and #include <stdlib.h>, and it should work.
I'm new to the world of C programming, and I as trying to code a primitive, terminal-based version of the "Hangman" game.
One of the steps doing this (or at least the way I am working on), is to create a second char array (next to the original char array that stores the word one needs to guess), filled with "*" for every Char of the original array, and display it. Although the rest of the programming part is not there yet (since I am not finished with it yet), I doubt it is relevant for now (however I allready know how to proceed, that is if I weren't bothered by some error-messages)....
Here's the code I have so far:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
void hiddenArray(char array[]);
char *secretWord;
char *arrayCover;
char letter;
int main(int argc, char *argv[]){
secretWord = "Test";
printf("Welcome to the Hangman!\n\n");
hiddenArray(secretWord);
printf("What is the hidden Word?: %c\n", *arrayCover);
printf("Guess a letter\n");
scanf("%c", &letter);
}
void hiddenArray(char array[]){
int size,i;
size = sizeof(*array);
for (i=0;i<size-1;i++){
*(arrayCover+i) = "*";
}
}
Now I have two issues... the first one:
I don't understand the error message I am getting after compilation:
pendu.c:41:19: warning: incompatible pointer to integer conversion assigning to 'char' from 'char [2]' [-Wint-conversion]
*(arrayCover+i) = "*";
^ ~~~
1 warning generated.
And my second question: the second Array created, filled with "*" is not being displayed, what did I do wrong?
I'd love for some help, cheers!
Your program have some errors to be corrected .
1) Your *arraycover is pointing to some unknown value, You have not initialized it.
2) sizeof(*array) should be sizeof(array)
3) *(arrayCover+i) = "*" should be *(arrayCover+i) = '*';
I suggest you not to create too many global variables when you dont really need them
Create char secretWord[100] = "Test" instead of char *secretWord
Try this
size = sizeof(arrayCover)/sizeof(char);
for (i=0;i<size-1;i++){
*(array+i) = '*';
}
Despite of all these, I think you need to allocate memory for arrayCover
arrayCover = malloc(sizeof(char) * number_of_elements);
"*" is a string. Use '*' instead to get the char.
"*" is a string which also contains \0 also, resulting to 2 characters. Instead use '*' which is just a character.
The function hiddenArray has the formal argument array which need to be used locally instead of arrayCover as below,
void hiddenArray(char array[]){
int size,i;
size = sizeof(array)/sizeof(array[0]);
for (i=0;i<size-1;i++){
*(array+i) = '*'; /* Or array[i] = '*' */
}
}
I'm trying to print all characters stored in hex array to the screen, one by one, but I get this strange error in line 16. As far as I know, %c should be expecting a char, not an int.
Why I'm getting this error?
Below is my code, thanks.
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <ctype.h>
#include <string.h>
int main()
{
char hex[8] = "cf0a441f";
int hexCounter;
char *currentHex;
for(hexCounter=0; hexCounter<strlen(hex); hexCounter++)
{
currentHex = &hex[hexCounter];
printf("%c",currentHex);
}
return 0;
}
You mean
printf("%c", *currentHex);
In my opinion you can remove the entire idea of currentHex since it just adds complexity for no value. Simply do:
printf("%c", hex[hexCounter]);
The important point is that you're supposed to pass the value of the character itself, not it's address which is what you're doing.
You have hex[hexCounter] as a char so when you set
currentHex = &hex[hexCounter];
you are setting currentHex to the address of a char, i.e. a char *. As such, in your printf you need
printf("%c",*currentHex);
What you are doing is unnecessary anyway, since you could just do
printf("%c",hex[hexCounter]);
currentHex should be of type char, not char *.
char currentHex;
[..]
currentHex = hex[hexCounter];
printf("%c",currentHex);
If you really want it to be a pointer, dereference it to print:
printf("%c",*currentHex);
Here's the modified code which runs fine for me -
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <ctype.h>
#include <string.h>
int main()
{
char hex[9] = "cf0a441f";
unsigned int hexCounter;
char *currentHex;
for(hexCounter=0; hexCounter<strlen(hex); hexCounter++)
{
currentHex = &hex[hexCounter];
printf("%c",*currentHex);
}
return 0;
}