strncmp/strcpy 破坏源代码

发布于 2024-10-21 15:44:09 字数 1254 浏览 5 评论 0原文

今天我试图与 char * string 变得友好......但似乎我失败了:) 每次我调用 strcmp/strncmp/strcpy 函数时,我的源代码都会损坏...

这是代码片段

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

struct student
{
    int UID;
    char name[20];
    char surname[20];
};

char * getString(int minChars, int maxChars);

struct student * myStud;

int main(int argc, char** argv) {

    myStud = (struct student*)malloc(sizeof(struct student));
    while(1)
    {
        printf("\nEnter new name: ");
        strcpy(myStud->name,getString(1,19));
        printf("\n The values is now %s",myStud->name);
    }
    return (EXIT_SUCCESS);
}

char * getString(int minChars, int maxChars)
{

    char string[maxChars+1];
scanAgain:
    scanf("%s",&string);
    if(strlen(string)<minChars)
    {
        printf("\nToo few symbols, try again: ");
        goto scanAgain;
    }
    if(strlen(string)>maxChars)
    {
        printf("\nToo many symbols, try again: ");
        goto scanAgain;
    }
    string[maxChars]='\0';
    return(string);
}

输出:

Enter new name: Alekasdasd

 The values is now Alekasda�#
Enter new name: 

我只是一个初学者,所以它可能非常简单...可能不是。 哦,顺便说一句,使用linux和netbeans作为SDK,gcc作为编译器。

today i was trying to get friendly with char * string... but it seems im failing :)
Every time i call strcmp/strncmp/strcpy function my source gets corrupted...

here is the snippet

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

struct student
{
    int UID;
    char name[20];
    char surname[20];
};

char * getString(int minChars, int maxChars);

struct student * myStud;

int main(int argc, char** argv) {

    myStud = (struct student*)malloc(sizeof(struct student));
    while(1)
    {
        printf("\nEnter new name: ");
        strcpy(myStud->name,getString(1,19));
        printf("\n The values is now %s",myStud->name);
    }
    return (EXIT_SUCCESS);
}

char * getString(int minChars, int maxChars)
{

    char string[maxChars+1];
scanAgain:
    scanf("%s",&string);
    if(strlen(string)<minChars)
    {
        printf("\nToo few symbols, try again: ");
        goto scanAgain;
    }
    if(strlen(string)>maxChars)
    {
        printf("\nToo many symbols, try again: ");
        goto scanAgain;
    }
    string[maxChars]='\0';
    return(string);
}

Output:

Enter new name: Alekasdasd

 The values is now Alekasda�#
Enter new name: 

im just a beginner so it might be something very simple... might be not.
oh and by the way, using linux and netbeans as SDK, gcc as compiler.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

神妖 2024-10-28 15:44:10
char * getString(int minChars, int maxChars)
{

    char string[maxChars+1];
    ...
    return(string);
}

这里的“string”数组仅分配给 getString() 函数的范围。一旦它返回(超出范围),它就不再存在,并将被程序的其余部分覆盖。 “return(string)”语句返回不再分配的数据的指针——而不是数据本身。发生这种情况是由于 C 中的隐式数组到指针转换。

您的 getString() 函数不应这样做,而应采用 char* 作为参数,该参数在调用函数中分配。

char * getString(int minChars, int maxChars)
{

    char string[maxChars+1];
    ...
    return(string);
}

The "string" array here is only allocated for the scope of the getString() function. Once it returns (goes out of scope), it ceases to exist and will be overwritten by the rest of your program. The "return(string)" statement returns the pointer of this data that's not allocated anymore -- not the data itself. This happens due to the implicit array-to-pointer conversion in C.

Instead of doing this, your getString() function should take a char* as an argument, which is allocated in the calling function.

作妖 2024-10-28 15:44:10

我发现 getString() 函数有两个问题:

  1. 字符串变量必须声明为静态,以便函数返回时不会释放(堆栈、弹出)用于它的内存。
  2. scanf() 的参数不需要 & 标记,而只是指向缓冲区的指针,string

也就是说,将以下行更改为:

char string[maxChars+1];
scanf("%s",&string);

阅读

static char string[maxChars+1];
scanf("%s",string);

手册页 man 3 scanf 中您不希望在 scanf() 调用中使用 & 符号的原因如下:

      s      Matches a  sequence  of  non-white-space  characters;  the  next
              pointer must be a **pointer to character array** that is long enough
              to hold the input sequence and the  terminating  null  character
              ('\0'), which is added automatically.  The input string stops at
              white space or at the  maximum  field  width,  whichever  occurs
              first.

I see two problems with your getString() function:

  1. The string variable must be declared static so that the memory used for it is not released (stack, popped) when the function returns.
  2. The parameter to scanf() you do not want the & token, but simply the pointer to the buffer, string.

That is, change the lines:

char string[maxChars+1];
scanf("%s",&string);

to read

static char string[maxChars+1];
scanf("%s",string);

The reason you do not want the ampersand in the scanf() call is the following from the man page, man 3 scanf:

      s      Matches a  sequence  of  non-white-space  characters;  the  next
              pointer must be a **pointer to character array** that is long enough
              to hold the input sequence and the  terminating  null  character
              ('\0'), which is added automatically.  The input string stops at
              white space or at the  maximum  field  width,  whichever  occurs
              first.
遇到 2024-10-28 15:44:10

240行不是“片段”。
正如詹姆斯在评论中建议的那样,将代码减少到重现问题所需的最少行数。在这个阶段,问题的原因对您来说应该很明显——如果没有尝试再次发帖。

240 lines is not a "snippet".
As James suggested in his comment, reduce the code to the minimum number of lines needed to reproduce the problem. At that stage the cause of the problem should become obvious to you -- if not try posting again.

浮生面具三千个 2024-10-28 15:44:09

您将返回一个指向堆栈变量的指针。

char * getString(int minChars, int maxChars)
{

    char string[maxChars+1];

当 getString 返回时,string 无效。您的返回值指向这个无效字符串。

使用:

char * getString(int minChars, int maxChars, char * string) {

    return string;
}
...
char string[100];
getString(1, 2, string);

另外,goto?请停止这种行为 - 使用 forwhile dodo while 而不是 goto

You're returning a pointer to a stack variable.

char * getString(int minChars, int maxChars)
{

    char string[maxChars+1];

When getString returns, string is invalid. Your return value points to this invalid string.

Use:

char * getString(int minChars, int maxChars, char * string) {

    return string;
}
...
char string[100];
getString(1, 2, string);

Also, goto? Stop that please - use for, while do, do while but not goto

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文