0

我有这个代码:

#include <stdio.h>

int main(void) {
    char p[5][5];
    int i,j;

    for(i=1;i<=1;i++){
        for(j=1;j<=2;j++) {
            printf("\nInput Product code %d of day %d: ", j,i);
            scanf("%s", &p[i][j]);
        }
    }

    for(i=1;i<=1;i++){
        for(j=1;j<=2;j++) {
            printf("\n\tProduct code %s day %d", &p[i][j],i);
        }
    }

}

此代码输出:

Input Product code 1 of day 1: hello

Input Product code 2 of day 1: hi

  Product code hhi day 1

Product code hi day 1

有谁知道为什么 hello 和 hi 相互连接而不是在第一个打印 hello ?

我对字符串进行了很多研究,但似乎没有一个比这个更好。

4

3 回答 3

2

p[][]不是字符串的双数组,而是字符的双数组。它有 5 行和 5 列,如下所示:

p[row][column] = 

 Row| Column ->         |
  v | 0 | 1 | 2 | 3 | 4 |
| 0 |   |   |   |   |   |
| 1 |   |   |   |   |   |
| 2 |   |   |   |   |   |
| 3 |   |   |   |   |   |
| 4 |   |   |   |   |   |

第一个scanf()在 i = 1, j = 1 时调用,并复制字符串“hello”,p[][]如下所示('\0' 是终止字符串的 NUL 字符):

    | 0 | 1 | 2 | 3 | 4 |
| 0 |   |   |   |   |   |
| 1 |   | H | e | l | l |
| 2 | o |\0 |   |   |   |
| 3 |   |   |   |   |   |
| 4 |   |   |   |   |   |

下次调用时,i = 1, j = 2:

    | 0 | 1 | 2 | 3 | 4 |
| 0 |   |   |   |   |   |
| 1 |   | H | h | i |\0 |
| 2 | o |\0 |   |   |   |
| 3 |   |   |   |   |   |
| 4 |   |   |   |   |   |

你可以这样写的一种方法:

#include <stdio.h>
#define MAX_CODE_LEN   80 /* or something */

int main(void) 
{
    char *code[5][5] = {0},
         currentCode[MAX_CODE_LEN] = {0};
    int day = 0,
        codeNum = 0;

    /* start loops at 0 */
    for ( day = 0; day < 5; day++ ) {

        for ( codeNum = 0; codeNum < 5; codeNum++ ) {
            int len = 0;

            printf("\nInput Product code %d of day %d: ", codeNum, day);
            scanf("%s", currentCode);

            /* len doesn't include NUL but malloc needs it */
            len = strlen(currentCode);

            /* yoda style so compiler catches assignment instead of equality */
            if ( 0 == len ) {
                /* if the user didn't enter a code move onto the next day */
                code[day][codeNum] = NULL;
                break;
            }
            len = len >= MAX_CODE_LEN? MAX_CODE_LEN - 1: len;
            code[day][codeNum] = malloc(len * sizeof(char) + 1);
            strcpy(code[day][codeNum], currentCode);
        }
    }

    for ( day = 0; day < 5; day++ ) {

        for ( codeNum = 0; codeNum < 5; codeNum++ ) {

            if ( NULL == code[day][codeNum] ) {
                /* no more codes for today */
                break;
            }
            printf("\n\tProduct code %s day %d", code[day][codeNum], day);
        }
    }

    return 0;
}
于 2013-05-14T16:40:34.333 回答
0
char p[5][5];

这是字符矩阵而不是字符串矩阵

和你的scanf(),你想为矩阵中的每个元素放置一个字符串。这是不可能的。

您必须使用以下定义之一:

1)

char p[5][5][MAX_SIZE_OF_INPUT_STRINGS];

并且 scanf 应该是

scanf("%s", p[i][j]);

2)

char *p[5][5];

并且 scanf 应该是

scanf("%ms", p[i][j]);

p[i][j]这里指向一个动态分配的内存,当你的程序变得无用时scanf(),你必须释放它free(p[i][j])p[i][j]

于 2013-05-14T15:54:41.223 回答
0

原因是因为字符串只是字符数组(由\0or终止null。现在,您正在索引字符,并且scanf只是获取传递给它的字符引用,并用它填充结构的其余部分,直到它完成填充细绳。

你正在做的是将 p 设置为

* * * * *
* h e l l
o\0 * * *
* * * * *
* * * * *

接着

* * * * *
* h h i\0
o\0 * * *
* * * * *
* * * * *

如果我是你,我会更接近这样的东西

char p[5][6];
int i,j;


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

    printf("\nInput Product code of day %d: ", i);
    scanf("%s", &p[i]);
}

for(i=0;i<2;i++)
{
    printf("%s\n", &p[i]);
}
于 2013-05-14T15:55:43.273 回答