I'm watching a course online learning C and I stumbled upon something that is crashing my program.
In the video they show the following code snippet :
#include <stdio.h>
int main()
{
char* ch;
int num = 12345;
sprintf(ch, "%d", num);
printf("%s\n", ch);
return(0);
}
I've decided to make my own little program and test it.
Here's the code I've written :
#include <stdio.h>
#define A 65
int main()
{
int n = A;
printf("n is equal to %d\n", n);
n = atoi("10");
printf("n is equal to %d\n", n);
char* ch;
sprintf(ch, "%d", n);
printf("ch is equal to %s\n", ch);
return 0;
}
When I run my program, the output is as follow :
n is equal to 65
n is equal to 10
After this part my program crashes.
I assume the sprintf function is causing this but I'm not sure why, I'm new to the language so I wouldn't know, I think I've done everything correctly judging by the code snippets that was shown in the video.
Could someone please explain me what I did wrong ?
Thanks in advance.
In the video they show the following code snippet: [...]
If this is a snippet that they say should work, stop watching that video: the snippet has undefined behavior, there is no chance that it would work properly unless by an unlucky coincidence.
I've decided to make my own little program and test it.
Your program has the same exact problem: the buffer to which sprintf is writing has not been initialized. Change the declaration of ch to allocate some space to it, like this:
char ch[20];
This will prevent your code from writing to memory pointed to by an uninitialized pointer, fixing the undefined behavior.
Could you explain to me how char* could be used?
If you would like to use char*, assign it a result of malloc of a proper size, and free the result at the end:
char *ch = malloc(20);
... // Put the rest of the code here
// Add this line before the end:
free(ch);
You need to alocate memory for ch or else use an array instead of a pointer.
char* ch = malloc(sizeyouwant * sizeof(char));
Where sizeyouwant is the number of characters you will store.
The problem is here:
char* ch;
this is just a char pointer, it needs to point to allocated memory to hold the string:
char ch[32];
Related
So I suck with functions and need to debug this. Im pretty sure the function ToPigLating does its job well at converting. However I just need help calling the function ToPigLatin inside of my main function. But when I try doing that I just get a bunch of error codes.
#include <stdlib.h>
#include <string.h>
#define LEN 32
char* ToPigLatin(char* word[LEN]){
char word[LEN];
char translation [LEN];
char temp [LEN];
int i, j;
while ((scanf ("%s", word)) != '\0') {
strcpy (translation, word);
//just pretend I have all the work to convert it in here.
} // while
}
int main(){
printf("Enter 5 words: ");
scanf("%s", word);
ToPigLatin();
}```
Roughly, variables only exist within the function they're declared in. The word in ToPigLatin exists only within ToPigLatin. It is not available in main. This lets us write functions without worrying about all the rest of the code.
You need to declare a different variable in main, it can also be called word, to store the input and then pass that into ToPigLatin.
Let's illustrate with something simpler, a function which doubles its input.
int times_two(int number) {
return number * 2;
}
We need to give times_two a number.
int main() {
// This is different from "number" in times_two.
int number = 42;
// We have to pass its value into time_two.
int doubled = times_two(number);
printf("%d doubled is %d\n", number, doubled);
}
Your case is a bit more complicated because you're working with input and memory allocation and arrays. I'd suggest just focusing on arrays and function calls for now. No scanf. No strcpy.
For example, here's a function to print an array of words.
#include <stdio.h>
// Arrays in C don't store their size, the size must be given.
void printWords(const char *words[], size_t num_words) {
for( int i = 0; i < num_words; i++ ) {
printf("word[%d] is %s.\n", i, words[i]);
}
}
int main(){
// This "words" variable is distinct from the one in printWords.
const char *words[] = {"up", "down", "left", "right"};
// It must be passed into printWords along with its size.
printWords(words, 4);
}
ToPigLatingToPigLating function expects to have a parameter like ToPigLating("MyParameter");
Hello there icecolddash.
First things first, there are some concepts missing. In main section:
scanf("%s", word);
You're probably trying to read a string format and store in word variable.
In this case, you should have it on your declaration scope. After some adjustment, it will look like this:
int main(){
char word[LEN];
As you defined LEN with 32 bytes maximum, your program will not be allowed to read bigger strings.
You're also using standard input and output funcitions as printf, and so you should ever include stdio.h, thats the header which cointains those prototypes already declared, avoiding 'implicit declaration' compiling warnings.
Next issue is how you're declaring your translation function, so we have to think about it:
char* ToPigLatin(char* word[LEN])
In this case, what you wrote:
ToPigLatin is a funcion that returns a char pointer, which means you want your function to probably return a string. If it makes sense to you, no problem at all. Although we got some real problem with the parameter char* word[LEN].
Declaring your variable like this, assume that you're passing an array of strings as a parameter. If I got it right, you want to read all five words in main section and translate each one of them.
In this case I suggest some changes in main function, for example :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LEN 32
#define MAX_WORDS 5
char *globalname = "translated";
char* ToPigLatin(char* word){
char *translation = NULL;
//Translation work here.
if ( !strcmp(word, "icecolddash") ){
return NULL;
}
translation = globalname;
return translation;
}
int main(){
char word[LEN];
char *translatedword;
int i;
printf("Enter 5 words: \n");
for ( i=0; i < MAX_WORDS; i++ ){
fgets(word, sizeof(word), stdin);
strtok(word, "\n"); // Just in case you're using a keyboard as input.
translatedword = ToPigLatin(word);
if ( translatedword != NULL ){
//Do something with your translation
//I'll just print it out as an example
printf("%s\n", translatedword);
continue;
}
// Generic couldn't translate message
printf("Sorry, I know nothing about %s\n", word);
}
return 0;
}
The above code translate every word in a fixed word "translated".
In case of reading the exact input "icecolddash", the program will output a generic error message, simulating some problem on translation process.
I hope this help you out with your studies.
There are a few things that I see.
#include <stdio.h>
#include <stdlib.h>
char* ToPigLatin(char* word){
printf(word);
return word;
}
int main(){
printf("Enter 5 words: ");
// declare the variable read into by scanf
char * word = NULL;
scanf("%s", word);
//Pass the variable into the function
ToPigLatin(word);
// Make sure you return an int from main()
return 0;
}
I left some comments in the code with some specific details.
However, the main thing that I would like to call out is the style of the way you're writing your code. Always try to write small, testable chunks and build your way up slowly. Try to get your code to compile. ALWAYS. If you can't run your code, you can't test it to figure out what you need to do.
As for the char ** comment you left on lewis's post, here is some reading you may find useful in building up your intuition:
https://www.tutorialspoint.com/what-does-dereferencing-a-pointer-mean-in-c-cplusplus
Happy coding!
My code is compiled fine but the second printf of my code is not printing.
#include<stdio.h>
int main()
{
char * const p="pointerconstant";
printf("%s",p);
*p='B';
printf("\n%s",p);
}
When I run the following program, it outputs..
pointerconstant
pointerconstant
But it should be..
pointerconstant
Bointerconstant
What is the problem here?
i think your issue is similar: https://stackoverflow.com/a/7547849/5809736
From #bdonlan for your code:
Note that if you did this, it would work:
char p[] = "pointerconstant";
printf("first=%s",p);
*p='B';
printf("\nsecond=%s",p);
This is because we're initializing a non-const character array. Although the syntax looks similar, it is treated differently by the compiler.
In this line
*p='B';
You're trying to modify the first byte of the char array that the pointer points to. This doesn't work because that's a read-only part of your program's binary. Fix it by copying it to the stack or heap:
#include<stdio.h>
#include<string.h>
int main()
{
char * const p = strdup("pointerconstant"); // string is copied to the heap
printf("first=%s", p);
*p = 'B';
printf("\nsecond=%s", p);
free(p); // copy of the string on the heap is released again
return 0; // 0 indicates that the program executed without errors
}
The result is:
first=pointerconstant
second=Bointerconstant
On a side note, in my opinion it would be more idiomatic to write *p = 'B'; as p[0] = 'B';, but that's up to you, of course.
Note: this answer is in C, the question is also tagged as C++
I'm trying to write a function that takes in two strings, concatenates them, and then writes them to a 2D array. I have been messing around with different things and looking at other posts to no avail. The seg fault seems to occur in the last strcpy when I'm trying to write the the concatenated string to the char array. If that line is commented out the program seems to work just fine.
void saveToArray(char *command1, char *command2)
{
char *saveCommands[30][100];
int *commands = malloc(sizeof(int));
char concatCommand[30];
strcpy(concatCommand, command1);
strcat(concatCommand, " ");
strcat(concatCommand, command2);
strcpy(*&saveCommands[0][*commands], concatCommand);
*commands += 1;
}
I apologize in advance for any formatting issues as this is my first post and thanks for any answers!
There are a number of scary things going on in this function. For starters...
int *commands = malloc(sizeof(int));
You don't free this or return it, so it is 100% a memory leak. I see no reason why you should want to allocate this integer on the heap rather than the stack.
char concatCommand[30];
strcpy(concatCommand, command1);
strcat(concatCommand, " ");
strcat(concatCommand, command2);
This could potentially overflow your buffer.
strcpy(*&saveCommands[0][*commands], concatCommand);
*& is a no-op (it doesn't do anything). You don't copy anything into commands, so *commands could be anything. Finally, the pointers in saveCommands aren't initialized so strcpy(saveCommands[x][y], "some string") will basically always segfault in practice. I think you might want this instead:
char saveCommands[30][100]
...
strcpy(&saveCommands[0][*commands], concatCommand);
I took the liberty to re-write your code a bit... too many characters make my eyes hurt... at any rate, this code works. It was mainly the strcpy dereference that was causing the issue.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void cmds(char *c1, char *c2) {
char sc[30][100];
int c = 0;
char cc[30];
strcpy(cc, c1);
strcat(cc, " ");
strcat(cc, c2);
strcpy(&sc[c][0], cc); // problem was here...
printf("%s\n", &sc[c][0]);
}
int main() {
char *c1 = "c001";
char *c2 = "c002";
cmds(c1, c2);
return 0;
}
I want to calculate length of string and copy the string to another without using c library function, but when I use fgets() function to read the string from keyboard, the code not showing the actual value of length as well as the destination string. I use the fgets() function instead of gets() because the compiler says that gets()function is "deprecated".but when I change sizeof(source) in the code to an integer value suppose 50 the code works fine. Can anybody tell me what wrong with this code and why on earth the compiler say that gets() function is deprecated.
This is the code:
#include <stdio.h>
#include <stdlib.h>
int len(char *source);
char *coppy(char *dest,char *source);
int main (void){
char *source,*dest;
source=(char *)malloc(len(source)+1);
printf("enter string:");
fgets(source,sizeof(source),stdin);
if(source[len(source)-1]=='\n'){
source[len(source)-1]='\0';
}
dest=(char *)malloc(len(source)+1);
coppy(dest,source);
printf("dest=%s\n",dest);
printf("length source=%d\n",len(source));
printf("length dest=%d\n",len(dest));
return 0;
}
int len(char *source){
int i=0;
while(*source!='\0'){
source++;
i++;
}
return i;
}
char *coppy(char *dest,char *source){
while(*source!='\0'){
*dest=*source;
source++;
dest++;
}
*dest='\0';
return dest;
}
This is the result when run that code:
enter string:programming
dest=pro
length source=3
length dest=3
Here is your first mistake:
source=(char *)malloc(len(source)+1)
You pass source to the function len before you initialized it, which is undefined behaviour. From hereon in, anything could happen.
The second mistake is your use of fgets:
fgets(source,sizeof(source),stdin);
The second argument to fgets is supposed to be how many characters are available to be written in, not sizeof(source). Read the documentation for fgets, and sizeof if necessary.
Your error is in how you allocate memory for source
source=(char *)malloc(len(source)+1);
What did you expect len(source) to be? Play computer and run through your len function. I'm surprised your code compiles and runs at all. Your len function on an uninitialized char* should be undefined behavior.
That is why your code fails, you are not allocating enough memory to hold your input string.
Below is my code snippet
struct encode
{
char code[MAX];
}a[10];
int main()
{
char x[]={'3','0','2','5','9','3','1'};
for(i=0;i<1;i++)
{
printf("%c",x[i]);
//This will printout like 3025931 now I want this to be stored in structure.
}
strcpy(a[0].code,x);
// or
a[0].code=x;//neither works
display();
}
void display()
{
printf("%c",a[0].code);
}
I want the output to be like:3025931.
Which I am not getting due to incompatible assign type. Please tell me where am i going wrong.
I see two problems here. The first is that the source of the strcpy is a where it probably should be x.
The second is that x is not null-terminated. Strings in C are null-terminated character arrays.
I would change the two lines:
char x[] = {'3','0','2','5','9','3','1'};
strcpy(a[0].code, a);
to:
char x[] = {'3','0','2','5','9','3','1', '\0'};
strcpy(a[0].code, x);
Here's a complete program that gives you what you want (it actually prints out the number twice, once in your inner loop character by character and once with the printf so that you can see they're the same):
#include <stdio.h>
#include <string.h>
#define MAX 100
struct encode {
char code[MAX];
} a[10];
int main() {
int i, j;
char x[] = {'3','0','2','5','9','3','1','\0'};
for(i = 0; i < 1; i++) {
for(j = 0; j < 7; j++) {
printf("%c", x[j]);
}
printf("\n");
strcpy(a[0].code, x);
}
printf("%s\n",a[0].code);
return 0;
}
Update based on comment:
I am sorry. I am new to C. My apologies for not pasting the code snippet correctly in the beginning: "printf("%c",a[0].code);" doesn't display "3025931".
No, it won't. That's because a[0].code is a character array (string in this case) and you should be using "%s", not "%c". Changing the format specifier in the printf should fix that particular issue.
Here,
strcpy(a[0].code, a);
did you mean
strcpy(a[0].code, x);
...?
Also, x needs to be null terminated, or you need to replace strcpy with strncpy or memcpy and pass in a length.
This line doesn't make much sense:
strcpy(a[0].code, a);
Perhaps you want this:
memcpy(a[0].code, x, sizeof x);
a[0].code[sizeof x] = '\0';
(The second line is necessary to nul-terminate code, making it a proper C string).
A lot of things are wrong in your program. The most offending line is this:
strcpy(a[0].code, a);
but there are other oddities as well, e.g.
display is never called
a is only assigned (kind of), but never read (except in display, which is never called)
the i loop makes no sense
Basically, this program looks like copy-pasted by someone who has no clue.