如何从 C 中的文本文件中剪切或截断行
How to cut or truncate lines from a text file in C
我正在读取每行超过 63 个字符的文件,我希望字符在 63 处被截断。但是,它无法截断从文件中读取的行。
在这个程序中我们假设文件有 10 行
目标: 我想从每行中读取 63 个字符。任何超过 63 个字符的行,将读取 63 个字符并截断其余字符。如果有更简单的方法,请告诉我。
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char a[10][63];
char line[255];
int count = 0;
//Open file
FILE *fp;
fp = fopen("lines.dat", "r");
//Read each line from file to the "line array"
while(fgets(line, 255,fp) != NULL)
{
line[63] = '[=10=]';
//copy the lines into "a array" char by char
int x;
for(x = 0; x < 64; ++x)
{
a[count][x] = line[x];
}
count++;
}
fclose(fp);
//Print all lines that have been copied to the "a array"
int i;
for(i = 0; i < 10; i++)
{
printf("%s", a[i]);
}
}
您的数组不够大,无法容纳 63 个字符和 字符串终止符。
char a[10][63];
应该是
char a[10][64];
然后你可以通过 63
正确索引字符串,因为索引范围是 0
..63
.
将字符串复制到数组中的更简单方法是使用库函数,您需要 #include <string.h>
while(fgets(line, 255, fp) != NULL)
{
line[63] = '[=12=]';
strcpy (a[count], line);
count++;
}
如 Weather Vane 所述,您的 char
矩阵不够宽,无法容纳 63 个字符的行 加上 最后的 '[=13=]'
.
您的代码还有其他问题:
你用 fgets(line, 255,fp)
读取行,然后在 63 个字符后强制使用 '[=13=]'
。如果该行超过 254 个字节怎么办?在下一次调用之前,该行的其余部分将在标准输入中保持未读状态,并且您的矩阵中将有一个或多个额外的错误行块。
您不处理行尾的换行符:如果一行被截断,它在矩阵中没有 '\n'
,而对于较短的行则有.
对于少于 63 个字符的行,您应该怎么办?别管他们?跳过他们?我知道您假设它们都至少有 63 个字符,但您的程序应该优雅且可预测地处理不符合要求的输入。
这是一个修改后的程序来执行此操作:
#include <stdio.h>
#define NROWS 10
#define NCOLS 63
int main(void)
{
char a[NROWS][NCOLS+1];
int row, col, c;
//Open file
FILE *fp;
fp = fopen("lines.dat", "r");
if (fp == NULL)
return 1;
for (row = 0; row < NROWS;) {
for (col = 0; (c = getc(fp)) != EOF;) {
if (c == '\n')
break;
if (col < NCOLS)
a[row][col++] = c;
}
//terminate the string.
a[row][col] = '[=10=]';
if (col == 0 && c == EOF)
break;
if (col < NCOLS) {
// handle short lines: here just accept them.
}
row++;
if (c == EOF)
break;
}
fclose(fp);
//Print all lines that have been copied to the "a array"
for (int i = 0; i < row; i++) {
printf("%s\n", a[i]);
}
}
我坚持要用fgets
,这里有一个替代方案:
#include <stdio.h>
#include <string.h>
#define NROWS 10
#define NCOLS 63
int main(void)
{
char a[NROWS][NCOLS+1];
char *p;
int row, c;
//Open file
FILE *fp;
fp = fopen("lines.dat", "r");
if (fp == NULL)
return 1;
for (row = 0; row < NROWS;) {
if (!fgets(a[row], NCOLS+1, fp))
break; // stop at EOF
if ((p = strchr(a[row], '\n')) != NULL)
*p = '[=11=]'; // accept short lines
row++;
// skip extra characters upto the end of line
while ((c = getc(fp)) != EOF && c != '\n')
continue;
if (c == EOF)
break;
}
fclose(fp);
//Print all lines that have been copied to the "a array"
for (int i = 0; i < row; i++) {
printf("%s\n", a[i]);
}
}
我正在读取每行超过 63 个字符的文件,我希望字符在 63 处被截断。但是,它无法截断从文件中读取的行。
在这个程序中我们假设文件有 10 行
目标: 我想从每行中读取 63 个字符。任何超过 63 个字符的行,将读取 63 个字符并截断其余字符。如果有更简单的方法,请告诉我。
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char a[10][63];
char line[255];
int count = 0;
//Open file
FILE *fp;
fp = fopen("lines.dat", "r");
//Read each line from file to the "line array"
while(fgets(line, 255,fp) != NULL)
{
line[63] = '[=10=]';
//copy the lines into "a array" char by char
int x;
for(x = 0; x < 64; ++x)
{
a[count][x] = line[x];
}
count++;
}
fclose(fp);
//Print all lines that have been copied to the "a array"
int i;
for(i = 0; i < 10; i++)
{
printf("%s", a[i]);
}
}
您的数组不够大,无法容纳 63 个字符和 字符串终止符。
char a[10][63];
应该是
char a[10][64];
然后你可以通过 63
正确索引字符串,因为索引范围是 0
..63
.
将字符串复制到数组中的更简单方法是使用库函数,您需要 #include <string.h>
while(fgets(line, 255, fp) != NULL)
{
line[63] = '[=12=]';
strcpy (a[count], line);
count++;
}
如 Weather Vane 所述,您的 char
矩阵不够宽,无法容纳 63 个字符的行 加上 最后的 '[=13=]'
.
您的代码还有其他问题:
你用
fgets(line, 255,fp)
读取行,然后在 63 个字符后强制使用'[=13=]'
。如果该行超过 254 个字节怎么办?在下一次调用之前,该行的其余部分将在标准输入中保持未读状态,并且您的矩阵中将有一个或多个额外的错误行块。您不处理行尾的换行符:如果一行被截断,它在矩阵中没有
'\n'
,而对于较短的行则有.对于少于 63 个字符的行,您应该怎么办?别管他们?跳过他们?我知道您假设它们都至少有 63 个字符,但您的程序应该优雅且可预测地处理不符合要求的输入。
这是一个修改后的程序来执行此操作:
#include <stdio.h>
#define NROWS 10
#define NCOLS 63
int main(void)
{
char a[NROWS][NCOLS+1];
int row, col, c;
//Open file
FILE *fp;
fp = fopen("lines.dat", "r");
if (fp == NULL)
return 1;
for (row = 0; row < NROWS;) {
for (col = 0; (c = getc(fp)) != EOF;) {
if (c == '\n')
break;
if (col < NCOLS)
a[row][col++] = c;
}
//terminate the string.
a[row][col] = '[=10=]';
if (col == 0 && c == EOF)
break;
if (col < NCOLS) {
// handle short lines: here just accept them.
}
row++;
if (c == EOF)
break;
}
fclose(fp);
//Print all lines that have been copied to the "a array"
for (int i = 0; i < row; i++) {
printf("%s\n", a[i]);
}
}
我坚持要用fgets
,这里有一个替代方案:
#include <stdio.h>
#include <string.h>
#define NROWS 10
#define NCOLS 63
int main(void)
{
char a[NROWS][NCOLS+1];
char *p;
int row, c;
//Open file
FILE *fp;
fp = fopen("lines.dat", "r");
if (fp == NULL)
return 1;
for (row = 0; row < NROWS;) {
if (!fgets(a[row], NCOLS+1, fp))
break; // stop at EOF
if ((p = strchr(a[row], '\n')) != NULL)
*p = '[=11=]'; // accept short lines
row++;
// skip extra characters upto the end of line
while ((c = getc(fp)) != EOF && c != '\n')
continue;
if (c == EOF)
break;
}
fclose(fp);
//Print all lines that have been copied to the "a array"
for (int i = 0; i < row; i++) {
printf("%s\n", a[i]);
}
}