1

今日、私は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をコンパイラーとして使用しています。

4

4 に答える 4

3

スタック変数へのポインタを返しています。

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?やめてください-、を使用しますがfor、使用しないでくださいwhile dodo whilegoto

于 2011-03-12T23:36:41.277 に答える
2
char * getString(int minChars, int maxChars)
{

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

ここでの「文字列」配列は、getString()関数のスコープにのみ割り当てられます。戻ると(スコープから外れると)、存在しなくなり、プログラムの残りの部分によって上書きされます。「return(string)」ステートメントは、データ自体ではなく、割り当てられなくなったこのデータのポインターを返します。これは、Cでの暗黙的な配列からポインターへの変換が原因で発生します。

これを行う代わりに、getString()関数は、呼び出し元の関数で割り当てられたchar*を引数として受け取る必要があります。

于 2011-03-12T23:36:55.587 に答える
1

getString()関数に2つの問題があります。

  1. static文字列変数は、関数が戻ったときに使用されたメモリが解放(スタック、ポップ)されないように宣言する必要があります。
  2. scanf()のパラメーターは&トークンではなく、単にバッファーへのポインターstringです。

つまり、行を変更します。

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

読む

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

呼び出しにアンパサンドが必要ない理由はscanf()、manページから次のとおりですman 3 scanf

      ■空白以外の文字のシーケンスに一致します。次
              ポインタは、十分な長さの**文字配列へのポインタ**である必要があります
              入力シーケンスと終了ヌル文字を保持します
              ('\ 0')、これは自動的に追加されます。入力文字列はで停止します
              空白または最大フィールド幅のいずれか発生する方
              最初。
于 2011-03-12T23:36:19.827 に答える
0

240行は「スニペット」ではありません。Jamesがコメントで示唆したように、問題を再現するために必要な最小行数にコードを減らします。その段階で、問題の原因が明らかになるはずです。そうでない場合は、もう一度投稿してください。

于 2011-03-12T23:47:18.523 に答える