我有一个赋值,我们从输入文件中获取内容并将其放入arrys,第一行上的数字表示数组的尺寸。前6涉及文本文件中的前6行/行,我已经将这些行/行放在一维射线中,但之后的字符必须以已解纵横字的形式(包括空格并确保‘\0’的5x7有n个额外列)将它们放入一个5x62d数组中,我必须使用malloc或calloc来生成数组,而我的问题是生成矩阵,因为它没有得到空格,或者我得到了分段转储。我试图先做数组(两个数组,一个W字符串的一维数组和一个2d字符数组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个单词作为字符串数组很好地打印出来,但是2d字符数组是我的不足之处。
钉钉
墨西哥薄饼卷
名字
男人
下一首
能
分段故障(堆芯倾弃)
发布于 2022-03-30 23:49:35
这里出了很多问题。我的第一个建议就是先让容易的一点发挥作用。将6个单词读入数组,然后打印出来。先让它起作用。(这在您的代码中不起作用,您没有保存单词然后在任何地方输入)。现在有什么不对劲的
fgets(inBuf, SIZE, input); // ok
sscanf(inBuf, "%i%i%i", &W, &N, &M); //ok下面这个词的目的是什么?它是由6个字符组成的数组。这似乎没有任何意义,因为6是单词的数量,而不是它们的长度。
word = (char *)malloc(sizeof(char) * W);
char *crossword[N];
char *ptr = word;
// char token[N][M]; <<<< dont need this yet
// ok this loop read W words from the input file.
for (int x = 0; x < W; x++)
{
fgets(inBuf, SIZE, input); // good
sscanf(inBuf, "%s", &words); // you could have fscanf directly but ok
printf("%s\n", words); // print it
*ptr = *words; // meaningless line
}我认为最后一行是试图将刚才读到的单词复制到缓冲区' word‘,因为您之前做了*ptr = word
首先,请注意奇怪的名字,我希望'word‘是数组或病房,’word‘是您刚刚读到的。
更重要的是,这不是复制字符串的方式。
所以让我们解决这个问题
首先,我们需要一系列指向单词的指针。
char *words[N];我不愿意输入它,因为它不是标准的c++,但是您每次使用它(变量长度数组,我的编译器根本不允许它,即使我问得很好)。但我会做的。
现在,我们需要一个char缓冲区来将当前单词读入
char word[SIZE]; // get rid of old word and words现在让我们来读一读
// get rid of old word and words
char word[SIZE];
char *words[N];
for (int x = 0; x < W; x++)
{
fgets(inBuf, SIZE, input);
sscanf(inBuf, "%s", &word);
words[x] = strdup(word);
}现在
for (int x = 0; x < W; x++)
{
printf("%s\n", words[x];
}为了证明我们真的有数据
在进入下一节之前,把所有的工作都做好
PS,strdup是一个很好的函数,它为字符串提供了正确的大小,然后将字符串复制到错误的缓冲区,返回指向新错误内存的指针。
发布于 2022-03-31 03:14:35
这个程序中有几个常见的错误。
如果fopen失败,则打印警告,但无论如何继续执行该程序。您应该在这里退出,或者以其他方式处理该事件,以防止将来读取失败。
将错误打印到标准错误流也是谨慎的做法。
if ((input = fopen(argv[1], "r")) == NULL)
{
/* printf("Error, the file %s cannot be opened\n", argv[1]); */
fprintf(sterr, "Failed to open [%s].\n", argv[1]);
return EXIT_FAILURE;
}铸造malloc (或calloc等)的结果在C中没有必要,可以安全地隐式地将void *提升到任何其他指针类型。
除此之外,sizeof (char)还保证是1。
/* word = (char *)malloc(sizeof(char) * W); */
word = malloc(W);在sscanf(inBuf, "%s", &words)中,&words是一个char (*)[SIZE],这是%s的错误类型。
不需要&。words的类型是char [SIZE],当传递给函数时,它将衰减为适当的char *类型。
fgets、fscanf和sscanf都可能失败。您应该警惕这一点,以防止程序的其余部分处理不正确的数据。
fgets在失败时返回NULL。*scanf函数返回成功转换的次数("%s"是一个转换,"%i%i%i"是三个)。
if (NULL == fgets(inBuf, SIZE, input))
/* handle this event */;
if (1 != sscanf(inBuf, "%s", words))
/* handle this event */;*ptr = *words;不执行字符串复制。实际上,它将words的第一个元素复制到ptr的第一个元素。
ptr = words将指定指针值。
=从不用于字符串复制,而是使用strcpy函数进行复制:
char one[64];
char two[] = "hello world."
strcpy(one, two);必须注意确保目标缓冲区有足够的空间供要复制的字符串(包括其空终止字节)使用。
crossword[y][z]是char。使用%c而不是%s打印单个字符。
printf(/* "%s" */ "%c", crossword[y][z]);scanf说明符%s跳过前导空格,开始将字符读入其缓冲区,并在遇到更多空白时停止。
sscanf(" e aa", "%s", buffer)的结果将使buffer等同于"e"。您将无法以这种方式解析包含空格的行。
字符集转换说明符(%[])可以用来克服这个限制,因为它允许读取空格。%[^\n]将读取所有字符,直到遇到换行符为止。
请注意,在没有限制字段宽度说明符的情况下使用%s或%[]作为gets是不安全的,因为您可以使缓冲区溢出。
char buffer[16];
if (1 == sscanf(" e aa\n", "%15[^\n]", buffer))
printf("[%s]", buffer); /* => [ e aa] */尽管如此,简单的解决方案是从输入缓冲区中删除换行符(用空终止字节替换它),如果它存在,并直接使用该缓冲区。
char input[] = " e aa\n";
input[strcspn(input, "\n")] = 0;crossword的元素初始化为
crossword[f] = (char *)malloc(N * sizeof(char));以N作为第二维度的长度。然后,它们被访问为
for (int z = 0; z < M; z++) {
/* ... */
crossword[y][z] = token[y][z];其中z依赖于不同的绑定(M而不是N)。如果N是5,而M是6,这将访问超出界限的内存。
通常,不需要所有这些不同的中间缓冲区(以及指向缓冲区的指针)。这可以用一个单独的缓冲区来读取每一行。
下面是一个包含一些帮助函数以减少代码重复的工作示例。程序的大部分在run函数中。应相对简单地遵循以下规定:
information
matrix
请注意,输入文件必须在需要填充到指定cols长度的行中包含尾随空格(如果尺寸过大,则会发生截断)。
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* output formatted message to stderr and exit program unsuccessfully */
static void panic(const char *fmt, ...) {
va_list args;
va_start(args, fmt);
vfprintf(stderr, fmt, args);
fputc('\n', stderr);
va_end(args);
exit(EXIT_FAILURE);
}
/* read a line of input into a size limited buffer; removes newline character */
static size_t read_file_line(char *buffer, int size, FILE *file) {
if (!fgets(buffer, size, file))
panic("Could not read user input.");
size_t length = strcspn(buffer, "\n");
buffer[length] = 0;
return length;
}
/* panic unless memory allocation successful */
static void *palloc(size_t bytes) {
void *p = malloc(bytes);
if (!p)
panic("Could not allocate %zu bytes.", bytes);
return p;
}
static void print_matrix(size_t r, size_t c, char (*m)[r][c]) {
putchar('+');
for (size_t i = 0; i < c; i++)
putchar('-');
puts("+");
for (size_t i = 0; i < r; i++) {
putchar('|');
for (size_t j = 0; j < c; j++)
putchar((*m)[i][j]);
puts("|");
}
putchar('+');
for (size_t i = 0; i < c; i++)
putchar('-');
puts("+");
}
static void run(FILE *file) {
size_t word_count;
size_t rows;
size_t cols;
char input[128];
/* read our header information */
read_file_line(input, sizeof input, file);
if (3 != sscanf(input, "%zu%zu%zu", &word_count, &rows, &cols))
panic("Could not read file header.");
/* allocate the word list, read and allocate each word */
char **words = palloc(sizeof *words * word_count);
for (size_t i = 0; i < word_count; i++) {
size_t len = read_file_line(input, sizeof input, file);
words[i] = palloc(len + 1);
strcpy(words[i], input);
}
/* allocate and read our matrix */
char (*matrix)[rows][cols] = palloc(sizeof *matrix);
for (size_t i = 0; i < rows; i++) {
size_t len = read_file_line(input, sizeof input, file);
if (len < cols)
panic("Insufficient column data: Required %zu, Read %zu", cols, len);
for (size_t j = 0; j < cols; j++)
(*matrix)[i][j] = input[j];
}
/* display our input */
for (size_t i = 0; i < word_count; i++)
printf("WORD: %s\n", words[i]);
print_matrix(rows, cols, matrix);
/* free the memory */
for (size_t i = 0; i < word_count; i++)
free(words[i]);
free(words);
free(matrix);
}
int main(int argc, char **argv) {
if (argc != 2)
panic("usage: %s FILENAME", argv[0]);
FILE *file = fopen(argv[1], "r");
if (!file)
panic("Could not open file [%s].", argv[1]);
run(file);
fclose(file);
}stdout
WORD: nail
WORD: taco
WORD: name
WORD: men
WORD: next
WORD: can
+------+
| next |
|namect|
| e aa|
| n nc|
| nail |
+------+https://stackoverflow.com/questions/71684889
复制相似问题