[英]Return pointer to array of strings C
我正在嘗試返回從文件中獲取的字符串數組。 文件看起來像這樣(第一行是單詞數,每行都是單詞)。 當函數結束時,我會在主要部分得到一些奇怪的輸出。 我想返回指向字符串數組的指針。 請注意,使用打印的代碼的某些部分用於檢查我的程序。
這是分配內存的函數:
char *generisiProstor(int n) {
return (char*)malloc(n*sizeof(char[20]));
}
這是從rijeci.txt
提取單詞的功能,應返回指向包含單詞的字符串數組的指針:
char* ucitajRijeci(int n) {
char i;
char *rijeci;
static const char filename[] = "rijeci.txt";
FILE *file;
file = fopen(filename, "r");
if (file != NULL)
{
char line[20];
int n;
fscanf(file, "%d", &n);
rijeci = generisiProstor(n);
if (rijeci == NULL) {
return NULL;
}
int i = -1;
fgets(line, 20, file); //skipping first line witch is integer and not needed
while (fgets(line, 20, file) != NULL)
{
printf("%s\n", line); //normal output
i++;
strcpy(rijeci + i, line);
printf("%s\n", rijeci + i); //normal expected output
}
for (i = 0; i < n; i++) {
printf("%s\n", rijeci + i); //wrong output
}
}
return rijeci;
}
主要
int main()
{
static const char filename[] = "rijeci.txt";
FILE *file;
file = fopen(filename, "r");
char *rijeci;
int i;
if (file != NULL)
{
char line[20];
int n;
fscanf(file, "%d", &n);
rijeci = ucitajRijeci(n);
printf("Here is the array: ");
for (i = 0; i < n; i++) {
printf("%s ", rijeci+i); //wrong output
}
}
return 0;
}
在這里,您必須使用二維數組(用char **
代替char *
)。 由於返回rijeci
數組,因此必須將rijeci
聲明為char **rijeci;
char **
。 rijeci + i
更改為rijeci[i]
。 試試這個修改后的代碼。 這將起作用:-
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
/* generisiProstor */
char **generisiProstor(int n)
{
char **c; // making 2-d array
c = (char **)malloc(n * sizeof(char *));
for (int i = 0; i < n; i++)
{
c[i] = (char *)malloc(20 * sizeof(char));
}
return c;
}
/* ucitajRijeci */
char **ucitajRijeci(int n)
{
char **rijeci; // change to char **
static const char filename[] = "rijeci.txt";
FILE *file;
file = fopen(filename, "r");
if (file != NULL)
{
char line[20];
int n;
fscanf(file, "%d", &n);
rijeci = generisiProstor(n);
if (rijeci == NULL)
{
return NULL;
}
int i = -1;
fgets(line, 20, file); //skipping first line witch is integer and not needed
while (fgets(line, 20, file) != NULL)
{
printf("%s\n", line); //normal output
i++;
strcpy(rijeci[i], line);
printf("%s\n", rijeci[i]); //changed to rijeci[i]
}
for (i = 0; i < n; i++)
{
printf("%s\n", rijeci[i]); //changed to rijeci[i]
}
}
return rijeci;
}
/* main() */
int main()
{
static const char filename[] = "rijeci.txt";
FILE *file;
file = fopen(filename, "r");
char **rijeci; // change to char **
int i;
if (file != NULL)
{
char line[20];
int n;
fscanf(file, "%d", &n);
rijeci = ucitajRijeci(n);
printf("Here is the array: ");
for (i = 0; i < n; i++)
{
printf("%s ", rijeci[i]); //changed to rijeci[i]
}
}
return 0;
}
你知道數組和字符串的定義嗎?
我會按照2011年C標准的要求將它們提供給您:
數組類型描述具有特定成員對象類型(稱為元素類型)的連續分配的非空對象集。 [...]
字符串是連續的字符序列,以第一個空字符結尾並包括第一個空字符。 [...]
因此, 數組是從完整對象類型派生的類型,但是字符串不是類型而是數據結構。
你非常高興。 您確定要強迫編譯器無理由地相信您是一個好習慣嗎? 還建議使用sizeof expr
不是sizeof (TYPE)
,因為一開始很難出錯,或者在以后進行重構時不同步。
考慮閱讀“ 我是否強制轉換malloc的結果? ”。
您遇到的第一個問題在這里:
char *generisiProstor(int n) {
return (char*)malloc(n*sizeof(char[20]));
}
您需要一個char指針數組,但是返回一個char指針或char數組。
這部分應該是:
char **generisiProstor(int n) {
return (char**)malloc(n*sizeof(char[20]));
}
char *rijeci
帶有相同的問題,您將其聲明為字符串或char指針。
您應該像此char **rijeci
一樣聲明它(在此情況下,您可能希望將其作為char *(rigeci[20])
),因此這將是一個字符串數組。
如果我的代碼正確,則此部分可能會出現另一個問題:
while (fgets(line, 20, file) != NULL)
{
printf("%s\n", line); //normal output
i++;
strcpy(rijeci + i, line);
printf("%s\n", rijeci + i); //normal expected output
}
在代碼的前面,您為n
單詞分配了內存。 在這里,您正在閱讀該行,並將其放入line
。 因此,當您讀取第一行時, i
為0
,但是在復制它之前先對其進行了遞增,因此您的數組未設置其第一次出現的狀態,並且您將最后一個字寫入未分配的內存中。
這部分應該是:
while (fgets(line, 20, file) != NULL)
{
printf("%s\n", line); //normal output
strcpy(rijeci + i, line);
i++
printf("%s\n", rijeci + i); //normal expected output
}
如果要返回大小為20的char數組的指針,則必須聲明該函數,如下所示:
char (*generisiProstor(int n))[20]
{
return malloc(n*sizeof(char[20]));
}
持有指向數組的指針的變量聲明為:
char (*rijeci)[20];
rijeci[i]
的類型為char[20]
,您可以在其中編寫字符串。
您正在分配正確的內存量,但是您需要更改使用方式。 malloc()
只能返回一個“平面”字符數組,因此generisiProstor()
的返回值是指向整個數組中第一個字符的簡單指針。
最初起作用的原因是每個字符串都會覆蓋前一個字符串的尾端,因此當您在讀入循環中執行打印輸出時,它們將正確顯示。 但是即使如此,您rijeci
數組的有效載荷也已完全損壞。
一種可能的解決方案是使用結構來保存您的文字:
struct Rijec
{
char rijec[20];
};
然后將generisiProstor(int n)
更改為:
struct Rijeci *generisiProstor(int n)
{
return malloc(n * sizeof(struct Rijec));
}
請注意,在C中不需要強制轉換,實際上應避免使用 。
然后,您需要將ucitajRijeci()
的頂部更改為如下所示:
struct Rijec *ucitajRijeci(int n)
{
struct Rijec *rijeci;
...
並且在所有使用rijeci + i
情況下,我都將rijeci + i
更改為rijeci[i].rijec
。
最終結果是,當您使用i
索引rijeci
數組中的單詞時,偏移量現在是正確的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.