strcat将垃圾添加到字符串

我试图在不改变单词顺序的情况下反转句子,

例如:“ Hello World” =>“ olleH dlroW”

这是我的代码:

#include <stdio.h>
#include <string.h>

char * reverseWords(const char *text);
char * reverseWord(char *word);

int main () {
  char *text = "Hello World";
  char *result = reverseWords(text);
  char *expected_result = "olleH dlroW";
  printf("%s == %s\n",result,expected_result);
  printf("%d\n",strcmp(result,expected_result));
  return 0;
}

char *
reverseWords (const char *text) {
  // This function takes a string and reverses it words.
  int i,j;
  size_t len = strlen(text);
  size_t text_size = len * sizeof(char);
  // output containst the output or the result
  char *output;

  // temp_word is a temporary variable,// it contains each word and it will be
  // empty after each space.
  char *temp_word;

  // temp_char is a temporary variable,// it contains the current character
  // within the for loop below.
  char temp_char;

  // allocating memory for output.
  output = (char *) malloc (text_size + 1);

  for(i = 0; i < len; i++) {

    // if the text[i] is space,just append it
    if (text[i] == ' ') {
      output[i] = ' ';
    }

    // if the text[i] is NULL,just get out of the loop
    if (text[i] == '\0') {
      break;
    }

    // allocate memory for the temp_word
    temp_word = (char *) malloc (text_size + 1);

    // set j to 0,so we can iterate only on the word
    j = 0;

    // while text[i + j] is not space or NULL,continue the loop
    while((text[i + j] != ' ') && (text[i + j] != '\0')) {

      // assign and cast test[i+j] to temp_char as a character,// (it reads it as string by default)
      temp_char = (char) text[i+j];

      // concat temp_char to the temp_word
      strcat(temp_word,&temp_char); // <= PROBLEM

      // add one to j
      j++;
    }

    // after the loop,concat the reversed version
    // of the word to the output
    strcat(output,reverseWord(temp_word));

    // if text[i+j] is space,concat space to the output
    if (text[i+j] == ' ')
      strcat(output," ");

    // free the memory allocated for the temp_word
    free(temp_word);

    // add j to i,so u can skip 
    // the character that already read.
    i += j;
  }

  return output;
}

char *
reverseWord (char *word) {
  int i,j;
  size_t len = strlen(word);
  char *output;

  output = (char *) malloc (len + 1);

  j = 0;
  for(i = (len - 1); i >= 0; i--) {
    output[j++] = word[i];
  }

  return output;
}

问题是我用<= PROBLEM标记的行,在第一个单词(在这种情况下为“ Hello”)上,一切正常。

在第二个单词(在本例中为“世界”)上,它向temp_word添加了垃圾字符, 我用gdb进行了检查,temp_char不包含垃圾,但是运行strcat时,附加在temp_word上的最新字符将类似于{{1} }

它将W\006附加到第二个单词内的所有字符,

我在终端上看到的输出很好,但是打印\006并将strcmpresult进行比较,则会返回expected_result

  • 可能是什么问题?
  • -94字符是什么?
  • 为什么\006添加它?
  • 如何防止这种行为?
urboat20 回答:strcat将垃圾添加到字符串

垃圾字符的根本原因是您为strcat函数的第二个参数使用了错误的输入。请参阅下面的说明:

在函数开始时,您声明:

  int i,j;
  size_t len = strlen(text);
  size_t text_size = len * sizeof(char);
  // output containst the output or the result
  char *output;

  // temp_word is a temporary variable,// it contains each word and it will be
  // empty after each space.
  char *temp_word;

  // temp_char is a temporary variable,// it contains the current character
  // within the for loop below.
  char temp_char;

您可以在堆栈中打印变量的地址,它们将是这样的:

printf("&temp_char=%p,&temp_word=%p,&output=%p,&text_size=%p\n",&temp_char,&temp_word,&output,&text_size);
result:    
&temp_char=0x7ffeea172a9f,&temp_word=0x7ffeea172aa0,&output=0x7ffeea172aa8,&text_size=0x7ffeea172ab0

如您所见,&temp_char(0x7ffeea172a9f)位于堆栈的底部,接下来的1个字节为&temp_word(0x7ffeea172aa0),接下来的8个字节为&output(0x7ffeea172aa8),依此类推(我使用的是64位操作系统,因此需要指针8个字节)

 // concat temp_char to the temp_word
  strcat(temp_word,&temp_char); // <= PROBLEM

在此处引用strcat描述:http://www.cplusplus.com/reference/cstring/strcat/

strcat第二个参数=&temp_char = 0x7ffeea172a9f。 strcat认为&temp_char(0x7ffeea172a9f)是源字符串的起点,而不是像您期望的那样仅添加一个char,而是将&temp_char(0x7ffeea172a9f)开头的所有字符追加到temp_word,直到遇到终止空字符

,

strcat()期望“ C”字符串的第一个字符的地址,实际上是char数组,其中至少一个元素等于'\0'

存储器temp_word既不指向也不满足这些要求。

由于此原因,调用了臭名昭著的未定义行为,此后可能发生任何事情。

可能的解决方法是更改​​

&temp_char

成为

      temp_word = (char *) malloc (text_size + 1);

还有这个

      temp_word = malloc (text_size + 1); /* Not the issue but the cast is 
                                             just useless in C. */
      temp_word[0] = '\0';

成为

        strcat(temp_word,&temp_char);

其余的代码可能还有其他问题。

,

strcat函数处理字符串。

在此代码段中

  // assign and cast test[i+j] to temp_char as a character,// (it reads it as string by default)
  temp_char = (char) text[i+j];

  // concat temp_char to the temp_word
  strcat(temp_word,&temp_char); // <= PROBLEM

指针temp_word和指针&temp_char都没有指向字符串。

例如,当源字符串由空格组成时,

此外,数组output不会附加以零结尾的字符。

无论如何,您的方法都过于复杂,并且具有许多冗余代码,例如,for循环中的条件和if语句中的条件彼此重复。

  for(i = 0; i < len; i++) {

    //…

    // if the text[i] is NULL,just get out of the loop
    if (text[i] == '\0') {
      break;
    }

该函数可以编写得更简单,如下面的演示程序所示。

#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>

char * reverse_words( const char *s )
{
    char *result = malloc( strlen( s ) + 1 );

    if ( result != NULL )
    {
        char *p = result;

        while ( *s != '\0' )
        {
            while ( isblank( ( unsigned char )*s ) )
            {
                *p++ = *s++;
            }


            const char *q = s;

            while ( !isblank( ( unsigned char )*q ) && *q != '\0' ) ++q;

            for ( const char *tmp = q; tmp != s; )
            {
                *p++ = *--tmp;
            }

            s = q;
        }

        *p = '\0';
    }

    return result;
}

int main(void) 
{
    const char *s = "Hello World";

    char *result = reverse_words( s );

    puts( s );
    puts( result );

    free( result );

    return 0;
}

程序输出为

Hello World
olleH dlroW
本文链接:https://www.f2er.com/2838837.html

大家都在问