问题
I have homework assignment: to write a function that reverse a string, and then write a function that reverses words in a string, using the first function. So if the input is: "have a nice day", the output will be: "day nice a have". I cannot understand why my code isn't working - I keep getting segmentation fault. The first function (reverse) works just fine. The problem is with the second one. I really need your help... Thank you in advance.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void reverse(char *a)
{
int i, j, size;
char tmp;
size = strlen(a);
j=size-1;
for(i=0; i<size/2; i++)
{
tmp=a[i];
a[i]=a[j];
a[j]=tmp;
j--;
}
}
void reverseAll(char *a)
{
int size;
reverse(a);
size = strlen(a);
char *new = (char*)malloc(size+1);
char *token = strtok(a, " ");
reverse(token);
strcpy(new, token);
printf("%s ", new);
while(token != NULL)
{
reverse(token);
token = strtok(NULL, " ");
strcat(new, token);
}
}
int main()
{
char a[15]= "have a nice day";
reverseAll(a);
printf("%s ", a);
return 0;
}
回答1:
reverse()
should work properly when a is null. And reverse(token)
should go after token = strtok(NULL, " ");
.
Code following works correctly.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void reverse(char *a)
{
int i, j, size;
char tmp;
if(!a)
return;
size = strlen(a);
j=size-1;
for(i=0; i<size/2; i++)
{
tmp=a[i];
a[i]=a[j];
a[j]=tmp;
j--;
}
}
void reverseAll(char *a)
{
int size;
reverse(a);
size = strlen(a);
char *new = (char*)malloc(size+1);
char *token = strtok(a, " ");
reverse(token);
strcpy(new, token);
//printf("%s ", new);
while(token != NULL)
{
token = strtok(NULL, " ");
reverse(token);
if(token){
strcat(new, " ");
strcat(new, token);
}
}
strcpy(a, new);
free(new);
}
int main()
{
char a[15]= "have a nice day";
reverseAll(a);
printf("%s ", a);
return 0;
}
回答2:
I'm afraid there are quite a few things to note here.
First things first, the reason you're getting your segfault is that you're changing your token from strtok before using it and therefore it ends up being NULL once you call strcat. That part of your code should look like this once you've fixed it:
char *token = strtok(a, " ");
reverse(token);
strcpy(new, token);
token=strtok(NULL," ");
while(token != NULL)
{
reverse(token);
strcat(new, token);
token = strtok(NULL, " ");
}
You'll still notice though that your program doesn't work correctly. Basically since your input is "have a nice day" what you'd want to output would be "day nice a have" but instead you get "yad" (note that your prints might be confusing as using printf inside of reverseAll without a newline character doesn't make for clear output...). A quick look through your code reveals the errors. Following is the working code and a few explanations which you probably should read through because at the end of the day those are that matter :)
void reverseAll(char *a)
{
int size;
reverse(a);
size = strlen(a);
char *new = (char*)malloc(size+1);
char *token = strtok(a, " ");
reverse(token);
strcpy(new, token);
token=strtok(NULL," ");
while(token != NULL)
{
strcat(new," ");
reverse(token);
strcat(new, token);
token = strtok(NULL, " ");
}
strcpy(a,new);
free(new);
}
What's happening is that you're making all your changes on the string you name as "new" but in reality what you're printing and what you want to effectively change is the string you've named a. Aside of that you've got a memory leak but that's of minor importance for now. I've kept the string you named as "new" in your code in case you want to do something with it later on but you could program it differently so that this variable isn't even needed. Furthermore you never introduce any spaces in your new string. Basically strtok will give you the words "day", "nice" and so on but not with the space character in them. So if you don't account for that your final string will look like "dayniceahave" instead of "day nice a have".
Last but not least: I think that if you had the time to think it through once more you'd figure out most of these yourself. That segfault was probably your most serious problem and when you have some spare time you should check out a tool named valgrind memcheck if you haven't already. It'll help you a ton when you run into similar scenarios.
Take care.
来源:https://stackoverflow.com/questions/59204364/reversing-words-in-a-string-in-c