将文件字符添加到2D动态阵列C编程
我有一个作业,我们从输入文件中获取内容并将其放入 arrys 中 第一行的数字表示数组的维度。前 6 个涉及文本文件中的前 6 行/行,我已将其放入一维射线中,但之后的字符我必须将它们以已解决的填字游戏的形式放入 5x6 二维数组中(带有空格)包含并确保有一个额外的列“\0”,所以 5x7) 我必须使用 malloc 或 calloc 来制作数组,我的问题是制作矩阵,因为它没有得到空格,或者我得到了分段转储。我尝试先创建数组(两个数组 - W 字符串的一维数组和 NxM 的二维字符数组)并确保元素位于矩阵中,但就像我说的那样,我不断收到分段转储。我不知道如何做到这一点。 txt 文件:
6 5 6
nail
taco
name
men
next
can
next
namect
e aa
n nc
nail
这是到目前为止我的代码:
void freeMatrix(char **matrix, int r, int c);
int main(int argc, char **argv)
{
int W, N, M;
char inBuf[SIZE], words[SIZE], crosswords[SIZE];
char *word;
char *outp;
FILE *input;
// FILE *output;
if (argc != 2)
{
printf("Error, please input the filenames\n");
exit(-1);
}
if ((input = fopen(argv[1], "r")) == NULL)
{
printf("Error, the file %s cannot be opened\n", argv[1]);
}
fgets(inBuf, SIZE, input);
sscanf(inBuf, "%i%i%i", &W, &N, &M);
word = (char *)malloc(sizeof(char) * W);
char *crossword[N];
char *ptr = word;
char token[N][M];
for (int x = 0; x < W; x++)
{
fgets(inBuf, SIZE, input);
sscanf(inBuf, "%s", &words);
printf("%s\n", words);
*ptr = *words;
}
for (int f = 0; f < N; f++)
{
crossword[f] = (char *)malloc(N * sizeof(char));
}
for (int y = 0; y < N; y++)
{
for (int z = 0; z < M; z++)
{
fscanf(input, "%c", &token[y][z]);
crossword[y][z] = token[y][z];
printf("%s", crossword[y][z]);
}
printf("\n");
}
fclose(input);
free(word);
freeMatrix(crossword, N, M);
return 0;
}
void freeMatrix(char **matric, int r, int c)
{
for (int i = 0; i < r; i++)
{
free(matric[i]);
}
free(matric);
}
我希望以与文本文件设置相同的方式使用矩阵中的各个字符打印填字游戏。导致分段错误。它将前 6 个单词很好地打印为字符串数组,但二维字符数组是我的不足之处。
指甲炸
玉米饼
名称
男士
下一个
可以
分段错误(核心已转储)
I have an assignment where we take in the contents from an input file and put it into arrys
the numbers on the first line represent the dimensions for the array. the first 6 regards the first 6 rows/lines on the text file, which i have put in a one dimensional ray but the characters after that i have to put them in a 5x6 2d array in the form of a solved crossword (with the spaces included and making sure to have a n extra column for '\0'so 5x7) I have to use malloc or calloc to make the array and my issue is making the matrix as it doesnt get the spaces or i get a segmentation dump. Im trying to make the arrays first(two arrays - one dimensional array of W strings and a 2d array of characters NxM) and make sure the elements are in the matrix but like i said i keep getting a segmentation dump. Im at a loss as to how to do this.
txt file:
6 5 6
nail
taco
name
men
next
can
next
namect
e aa
n nc
nail
here's my code so far:
void freeMatrix(char **matrix, int r, int c);
int main(int argc, char **argv)
{
int W, N, M;
char inBuf[SIZE], words[SIZE], crosswords[SIZE];
char *word;
char *outp;
FILE *input;
// FILE *output;
if (argc != 2)
{
printf("Error, please input the filenames\n");
exit(-1);
}
if ((input = fopen(argv[1], "r")) == NULL)
{
printf("Error, the file %s cannot be opened\n", argv[1]);
}
fgets(inBuf, SIZE, input);
sscanf(inBuf, "%i%i%i", &W, &N, &M);
word = (char *)malloc(sizeof(char) * W);
char *crossword[N];
char *ptr = word;
char token[N][M];
for (int x = 0; x < W; x++)
{
fgets(inBuf, SIZE, input);
sscanf(inBuf, "%s", &words);
printf("%s\n", words);
*ptr = *words;
}
for (int f = 0; f < N; f++)
{
crossword[f] = (char *)malloc(N * sizeof(char));
}
for (int y = 0; y < N; y++)
{
for (int z = 0; z < M; z++)
{
fscanf(input, "%c", &token[y][z]);
crossword[y][z] = token[y][z];
printf("%s", crossword[y][z]);
}
printf("\n");
}
fclose(input);
free(word);
freeMatrix(crossword, N, M);
return 0;
}
void freeMatrix(char **matric, int r, int c)
{
for (int i = 0; i < r; i++)
{
free(matric[i]);
}
free(matric);
}
I expected a crossword to be printed with the individual characters in the matrix the same way the text file has it set up. A segmentation error resulted. It prints the first 6 words fine as an array of strings but the 2d array of characters is where i fall short.
nail
taco
name
men
next
can
Segmentation fault (core dumped)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这里有很多事情是错误的。我的第一个建议是先让简单的部分开始工作。将这 6 个字读入一个数组,然后打印出来。首先让其发挥作用。 (目前这在您的代码中不起作用,您不会保存单词然后在任何地方输入)。现在出了什么问题,
下面这个词的目的是什么?它是一个 6 个字符的数组。似乎没有意义,因为 6 是单词的数量,而不是单词的长度
我认为最后一行以某种方式试图将您刚刚读到的单词复制到缓冲区“word”中,因为您做了
*ptr = word
早先首先注意奇怪的名称,我希望“words”是数组或病房,“word”是您刚刚读到的那个。
更重要的是,这不是你复制字符串的方式
所以让我们解决这个问题
首先我们需要一个指向单词的指针数组
我不愿意输入它,因为它不是标准的c,但你在任何地方都使用它(可变长度数组,我的编译器不允许它在所有,即使我问得很好)。但我会做的。
现在我们需要一个字符缓冲区来读取当前单词,
让我们做一些阅读
现在
来证明我们确实有数据
在继续下一节之前得到所有的工作
PS,strdup 是一个很棒的函数,它可以为单词分配正确的大小string,然后将字符串复制到 mallocd 缓冲区,返回指向新 mallocd 内存的指针
A lot of things wrong here. My first suggestion is just to get the easy bit working first. Read in the 6 words into an array and then print them out. Get that working first. (that isnt working in your code at the moment, you do not save the words then get entered anywhere). Here is whats wrong at the moment
what is the purpose of word below? It is an array of 6 characters. There seems no point to it since 6 is the number of words, not the length of them
I think that last line is somehow trying to copy the word you just read into the buffer 'word' given that you did
*ptr = word
earlierFirst note the odd names, I would expect 'words' to be the array or wards and 'word' to be the one you just read.
More importantly thats not how you copy strings
So lets fix this
First we need an array of pointers to words
I am reluctant to type that because its not standard c but you use it every where (Variable length arrays, my compiler does not allow it at all, even if I ask really nicely). But I will do it.
now we need a char buffer to read the current word into
now lets do some reading
now
to prove we actually have the data
get all that workinig before moving on to the next section
PS, strdup is a wonderful function that mallocs the correct size for the string and then copies the string to the malloced buffer, returnig a pointer to the newly mallocd memory
该程序中存在一些常见的错误。
如果
Fopen
失败,则打印警告,但无论如何继续使用该程序。您应该在此处退出,或以其他方式处理事件,以防止将来的阅读失败。将错误打印到标准误差流也将是谨慎的。
施放
malloc
的结果(或calloc
等)。其他指针类型。除此之外,保证
sizeof(char)
是1
。在
sscanf(inbuf,“%s”,&amp; words)
,&amp; words
是char> char(*)[size]
,哪个是%s
的错误类型。不需要
&amp;
。单词
是类型char [size]
,将 decay 转换给适当的char *
输入到功能。fgets
,fscanf
和sscanf
都可能失败。您应该防止这种情况,以防止其余程序使用不正确的数据。fgets
返回null
失败。*scanf
函数返回成功转换的数量执行(“%s”
是一种转换,“%i%i%i%i i i “
是三个)。*ptr = *单词;
不执行字符串副本。实际上,它将单词
的第一个元素复制到ptr
的第一个元素。ptr =单词
将分配指针值。=
从不用于字符串复制,而是使用strcpy
函数进行复制:必须注意确保目标缓冲区在to-to-to-被填充的字符串(包括其空的终止字节)。
填字游戏[y] [z]
是char
。使用%c
不是%s
打印单个字符。scanf
指定器%s
跳过领先的空格,开始将字符读取到其缓冲区中,并在遇到更多空间时停止。sscanf(“ e aa”,“%s”,buffer)
的结果将具有buffer
等效于“ e”
。您将无法使用其中的空间来解析线路。字符集转换说明器(
%[]
)可用于克服此限制,因为它允许阅读空格。%[^\ n]
将读取所有字符,直到它遇到新线为止。请注意,使用
%s
或%[]
而无需限制字段宽度指定不安全,因为get> get
,您可以溢出缓冲区。话虽如此,简单的解决方案是只要从输入缓冲区中删除新线(用零件终止字节),如果存在,则直接使用该缓冲区。
填字游戏的元素
与n
作为第二维度的长度进行初始化。然后将它们访问为z
依赖于其他界限(m
而不是n
)。如果n
是5
,并且m
是6
,则将访问内存。通常,不需要所有这些不同的中间缓冲液(以及缓冲区的指针)。这可以使用单个缓冲区来读取每一行。
这是一个具有一些辅助功能的工作示例,以减少代码重复。该程序的大部分位于
运行
函数中。遵循的内容应该相对简单:,请注意,输入文件必须包含在需要填充到指定<<<的行上的落后空间代码> cols 长度(如果超大,则会发生截断)。
Stdout
:There are several common mistakes present in this program.
If
fopen
fails, you print a warning but continue with the program anyway. You should exit here, or otherwise handle the event to prevent future reads from failing.It would also be prudent to print errors to the standard error stream.
Casting the result of
malloc
(orcalloc
, etc.) is not necessary in C. Avoid *
can be safely and implicitly promoted to any other pointer type.In addition to this,
sizeof (char)
is guaranteed to be1
.In
sscanf(inBuf, "%s", &words)
,&words
is achar (*)[SIZE]
, which is the wrong type for%s
.The
&
is not needed.words
is of typechar [SIZE]
, which will decay to the appropriatechar *
type when passed to a function.fgets
,fscanf
, andsscanf
can all fail. You should guard against this to prevent the rest of your program working with incorrect data.fgets
returnsNULL
on failure.*scanf
functions return the number of successful conversions performed ("%s"
is one conversion,"%i%i%i"
is three).*ptr = *words;
does not perform a string copy. Actually, it copies the first element ofwords
to the first element ofptr
.ptr = words
would assign the pointer value.=
is never used for string copying, and instead, copying is done with thestrcpy
function:Care must be taken to ensure that the destination buffer has enough space for the to-be-copied string (including its null terminating byte).
crossword[y][z]
is achar
. Use%c
not%s
to print single characters.The
scanf
specifier%s
skips leading whitespace, begins reading characters into its buffer, and stops when it encounters more whitespace.The result of
sscanf(" e aa", "%s", buffer)
would havebuffer
be equivalent to"e"
. You will not be able to parse the lines with spaces in them this way.The character set conversion specifier (
%[]
) can be used to overcome this limitation, as it allows reading whitespace.%[^\n]
will read all characters until it encounters a newline.Note that using either
%s
or%[]
without a limiting field width specifier is unsafe asgets
, as you can overflow the buffer.With that said, the simple solution is to just remove the newline from the input buffer (replace it with the null terminating byte), if it exists, and use that buffer directly.
The elements of
crossword
are initialized aswith
N
as the length of the second dimension. They are then accessed aswhere
z
relies on a different bound (M
instead ofN
). IfN
is5
, andM
is6
, this will access memory out of bounds.In general, there is no need for all these different, intermediate buffers (and pointers to buffers). This can be done with a single buffer for reading each line.
Here is a working example with some helper functions to reduce code repetition. The bulk of the program is in the
run
function. It should be relatively straightforward to follow along:Note that the input file must contain trailing whitespace on lines that require padding up to the specified
cols
length (truncation occurs if oversized).stdout
: