无法写入 char* 传递的参数函数,它崩溃了

问题描述 投票:0回答:1

我正在更新一个旧程序和函数 CleanStr() ,它应该删除字符串开头和结尾的所有制表符和空格。问题是,当我最后调用 strcpy() 并尝试修改提供的参数 C 字符串时,它崩溃了。问题不在于所提供字符串的空终止,这是在其他地方检查的并且它始终有效。

这是代码:

bool IsEmptyChar(char tchar)
{
    if (tchar == 0x09 || tchar == 0x0D || tchar == 0x0A || tchar == ' ')
        return true;

    return false;
}

char* CleanStr(char* tstr)
{
    int len = strlen(tstr);

    if (len <= 0)
        return tstr;

    char tempstr[MAX_ST_SIZE];
    memset(tempstr, NULL, MAX_ST_SIZE);

    unsigned int pos1 = 0;
    unsigned int pos2 = len;

    // get starting pos
    while (IsEmptyChar(tstr[pos1]) && pos1 < MAX_ST_SIZE - 1)
        pos1++;

    // get final pos
    while ((IsEmptyChar(tstr[pos2]) || tstr[pos2] == NULL) && pos2 > 0)
        pos2--;

    // Parse string into limits 
    unsigned int a;
    for (a = pos1; a < pos2 + 1; a++)
        tempstr[a - pos1] = tstr[a];

    strcpy(tstr, tempstr); // This line makes program crash

    return tstr;
}
c parameters c-strings
1个回答
0
投票

代码存在一些小问题,已通过以下更改和保护措施得到纠正:

  • MAX_ST_SIZE
    是为
    CleanStr()
    中的临时缓冲区和 main 中的输入缓冲区定义的。 strcpy()
     从内部
    CleanStr()
     现在可以说更安全了。
  • get final pos
     
    while()
    条件已更新,以防止
    pos2
    的病理条件变得小于
    pos1
  • NULL
     在 2 个位置使用不当(特别是如果 
    NULL
     被定义为您平台的 
    ((void *)0)
    )。 
    NULL
     中的 
    memset()
    '\0'
     代码块的 
    while()
     中的 
    get final pos
     被替换为零 (0)。
经过测试、可运行的代码位于

here

#include <stdio.h> #include <string.h> #include <stdlib.h> #include <stdbool.h> /* bool, true, false */ #define MAX_ST_SIZE 40 bool IsEmptyChar(char tchar) { if (tchar == 0x09 || tchar == 0x0D || tchar == 0x0A || tchar == ' ') return true; return false; } char* CleanStr(char* tstr) { int len = strlen(tstr); if (len <= 0) return tstr; char tempstr[MAX_ST_SIZE]; memset(tempstr, 0, MAX_ST_SIZE); /* Updated */ unsigned int pos1 = 0; unsigned int pos2 = len; // get starting pos while (IsEmptyChar(tstr[pos1]) && pos1 < MAX_ST_SIZE - 1) pos1++; // get final pos while ((IsEmptyChar(tstr[pos2]) || tstr[pos2] == '\0') && pos2 > pos1) /* Updated */ pos2--; // Parse string into limits unsigned int a; for (a = pos1; a < pos2 + 1; a++) tempstr[a - pos1] = tstr[a]; strcpy(tstr, tempstr); // This line (no longer) makes program crash return tstr; } int main() { char s1[MAX_ST_SIZE]={' ','\n','\t','\n','\r','H','e','l','l','o',' ','W','o','r','l','d','\n','\t','\n','\r', ' '}; char s2[MAX_ST_SIZE]={' ','\n','\t','\n','\r', '\n','\t','\n','\r', ' '}; char *res = CleanStr(s1); printf("Res: %s\n", res); res = CleanStr(s2); printf("Res: %s\n", res); return 0; }
输出:

Res: Hello World Res:
    
© www.soinside.com 2019 - 2024. All rights reserved.