在C程序中,从输入文件中删除选定行的第二列
该计划的主要目标:在C程序中,从输入文件中删除选定行的第二列,c,file,file-handling,C,File,File Handling,该计划的主要目标: 打印第一列中的数字位于起始值和停止值之间的行,这取决于用户输入。但是开始和停止的数字应该比较每行的第一个字 比如说, start = 770 stop = 791 它应该只比较每行的第一个整数 删除每行的第二列,并在每行末尾添加(1或任意数字),如示例输出格式 请给我一些操作说明 我试着写C代码,但没能做到。我附上这封信供你仔细阅读 输入文件格式 输出格式 代码 #包括 #包括 #包括 文件*file1; 文件*out1; ///函数声明 void OpenIn
start = 770
stop = 791
它应该只比较每行的第一个整数#包括
#包括
#包括
文件*file1;
文件*out1;
///函数声明
void OpenInputFile();
int-Extract\u-SOLID\u值(int-To\u-Find\u节点、int-To\u-Element\u-set\u列表);
int main()
{
int结果;
OpenInputFile();
int元素_固体;
int STOP;
开始=10;
停止=100;
///打开txt文件进行写入
out1=fopen(“output.txt”,“w”);
如果(out1==NULL)
{
佩罗尔(“福彭”);
退出(退出失败);
}
结果=提取实体值(开始、停止);
printf(“%s”,结果);
fclose(文件1);
fclose(out1);
返回0;
}///端干管
int-Extract\u-SOLID\u值(int-To\u-Find\u节点,int-To\u-Element\u-set\u列表)
{
字符行[256];
int字;
如果(!file1){
佩罗尔(“福彭”);
退出(退出失败);
}
而(fscanf(文件1,“%s%*[^\n]”,word)){
如果(字==开始){
fgets(行、sizeof(行)、file1);
如果(字==停止){
返回;
}
printf(“%s\n”,第行);
fprintf(out1,“%s\n”,行);
}
}
返回0;
}
void OpenInputFile(){
file1=fopen(“simple_csd example.dat”,“r”);
//检查文件是否存在
如果(!file1){
佩罗尔(“福彭”);
退出(退出失败);
}
返回;
}
您已经将开始
和停止
的值分别作为到查找节点
和到元素设置列表
到函数提取实心值()
因此,请在该函数中使用新名称,否则会出现错误,因为START
和STOP
不在该函数的范围内
您已经检查了输入文件是否是在OpenInputFile()
中创建的,那么在Extract\u SOLID\u value()
中的循环之前为什么还要再次检查
当一行中的第一个值在所需范围内时,需要继续扫描输入文件并将数据写入输出文件。
一个fgets()
是不行的,你必须依赖循环
int Extract_SOLID_value( int To_Find_node, int To_Element_set_list)
{
char line[256];
int word;
int fword;
while (fscanf(file1,"%d",&fword)==1){
if (fword >= To_Find_node && fword <=To_Element_set_list ){
fprintf(out1, "%d ", fword);
fprintf(stdout, "%d ", fword);
fscanf(file1, "%d", &word);
fgets(line, sizeof(line), file1);
line[strlen(line)-1]='\0';
fprintf(out1, "%s 1\n", line);
fprintf(stdout, "%s 1\n", line);
}
else
{
fgets(line, sizeof(line), file1);
}
}
return 0;
}
int-Extract\u-SOLID\u值(int-To\u-Find\u节点,int-To\u-Element\u-set\u列表)
{
字符行[256];
int字;
int fword;
而(fscanf(文件1、%d、&fword)==1){
如果(fword>=To_Find_node&&fword有很多方法可以进行此练习。除了基本的文件处理外,主要目标是认识到您需要将列值同时作为整数和字符串处理。(第一列是唯一需要整数值的列)
认识到您的比较需要一个整数值,您可以读取整行,然后使用sscanf
将第一列转换为int
,或者立即开始将每列标记为字符串,并使用strtol
将第一列转换为int
(任何一种方法都可以)
更大的问题是对行进行标记。(典型的选择是strtok
——名称恰当)。您也可以简单地使用一对指针和“inch-worm”从行首到行尾,边走边挑选列。然而,对于简单的空格或制表符分隔列,strtok
使之变得容易。这是一种方便的方法,可以分隔行中未知数量的列,因为格式化输入函数将失败
(注意:如果需要保留具有空值的列,也可以使用strep
函数,例如在.csv文件中,可能有col1、col2、col4
)
使用strtok
和strtol
执行到int
的转换的实现可能如下所示:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
/* constants for max chars, start & stop values */
enum { BASE = 10, MAXC = 512, START = 770, STOP = 791 };
int main (int argc, char **argv) {
char buf[MAXC] = ""; /* line buffer */
/* open file (or read from stdin -- default) */
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
if (!fp) { /* validate file open for reading */
fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
return 1;
}
while (fgets (buf, MAXC, fp)) { /* read each line */
int val; /* 1st col value */
size_t len = strlen (buf); /* get buf len for validation */
char *p, *delim = " \t\n"; /* pointer & delimiters */
if (len && buf[len - 1] != '\n') { /* validate complete line */
fprintf (stderr, "error: line exceeds %d chars.\n", MAXC);
return 1;
}
p = strtok (buf, delim); /* parse 1st column (as string) */
if (p == NULL) { /* handle 1st col error */
fprintf (stderr, "error: parse of first column failed.\n");
return 1;
}
errno = 0;
val = (int)strtol (p, NULL, BASE); /* convert to long/int */
if (errno) {
fprintf (stderr, "error: strtol() conversion failed.\n");
return 1;
}
/* for each line between START & STOP (inclusive) */
if (START <= val && val <= STOP) {
printf ("%d", val); /* output 1st col */
/* tokenize line, remove 2nd column, append 1 at end */
p = strtok (NULL, delim); /* parse/discard 2nd column */
if (!p) { /* handle failure to parse 2nd column */ }
p = strtok (NULL, delim); /* parse 3rd column */
if (!p) { /* handle failure to parse 3rd column */ }
while (p) { /* while token read */
printf (" %-8s", p); /* print token */
p = strtok (NULL, delim); /* parse next token/column */
}
printf ("1\n"); /* print final 1 at end */
}
}
if (fp != stdin) fclose (fp); /* close file if not stdin */
return 0;
}
#include <stdio.h>
#include <string.h>
/* constants for max chars, start & stop values */
enum { MAXC = 512, START = 770, STOP = 791 };
int main (int argc, char **argv) {
char buf[MAXC] = ""; /* line buffer */
/* open file (or read from stdin -- default) */
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
if (!fp) { /* validate file open for reading */
fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
return 1;
}
while (fgets (buf, MAXC, fp)) { /* read each line */
int val; /* 1st col value */
size_t len = strlen (buf); /* get buf len for validation */
char *p, *delim = " \t\n"; /* pointer & delimiters */
if (len && buf[len - 1] != '\n') { /* validate complete line */
fprintf (stderr, "error: line exceeds %d chars.\n", MAXC);
return 1;
}
if (sscanf (buf, "%d", &val) != 1) { /* convert 1st col to int */
fprintf (stderr, "error: conversion failure column 1.\n");
return 1;
}
/* for each line between START & STOP (inclusive) */
if (START <= val && val <= STOP) {
/* tokenize line, remove 2nd column, append 1 at end */
p = strtok (buf, delim); /* parse 1st column */
if (p == NULL) { /* handle 1st col error */
fprintf (stderr, "error: parse of first column failed.\n");
return 1;
}
printf ("%s", p); /* print column 1 */
p = strtok (NULL, delim); /* parse/discard 2nd column */
if (!p) { /* handle failure to parse 2nd column */ }
p = strtok (NULL, delim); /* parse 3rd column */
if (!p) { /* handle failure to parse 3rd column */ }
while (p) { /* while token read */
printf (" %-8s", p); /* print token */
p = strtok (NULL, delim); /* parse next token/column */
}
printf ("1\n"); /* print final 1 at end */
}
}
if (fp != stdin) fclose (fp); /* close file if not stdin */
return 0;
}
(注意:输出相同)
可以说,第一个更优雅,第二个让sscanf
处理转换和内部验证
请查看所有答案,如果您还有其他问题,请告诉我
作为功能的实施
作为对您上一条评论的回应,由于main()
本身只是一个函数,因此将代码转换为独立函数相对简单。传统上,您会在调用函数中打开/验证文件(在本例中,调用parsecolumns
函数的函数--main()
),然后只需将打开的文件*
文件流作为参数传递给函数
下面显示了一个快速实现(对用户输入filename
进行了合理验证)。如果用户通过使用CTRL+D或CTRL+Z(在windoze上)生成手动EOF
来取消输入,请始终验证所有用户输入,并始终检查EOF
#包括
#包括
#包括
#包括
/*最大字符数、开始和停止值的常数*/
枚举{BASE=10,MAXC=512,START=770,STOP=791};
int parsecolumns(文件*fp);
内部主(空){
字符文件名[MAXC]=“”;
FILE*fp=NULL;
for(;;){/*循环,直到提供好的文件名(或取消)*/
int rtn;/*始终捕获并验证scanf返回*/
printf(“输入文件名:”);
如果((rtn=scanf(“%s”,文件名))!=1){
如果(rtn==EOF){
fprintf(标准,“用户可
int Extract_SOLID_value( int To_Find_node, int To_Element_set_list)
{
char line[256];
int word;
int fword;
while (fscanf(file1,"%d",&fword)==1){
if (fword >= To_Find_node && fword <=To_Element_set_list ){
fprintf(out1, "%d ", fword);
fprintf(stdout, "%d ", fword);
fscanf(file1, "%d", &word);
fgets(line, sizeof(line), file1);
line[strlen(line)-1]='\0';
fprintf(out1, "%s 1\n", line);
fprintf(stdout, "%s 1\n", line);
}
else
{
fgets(line, sizeof(line), file1);
}
}
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
/* constants for max chars, start & stop values */
enum { BASE = 10, MAXC = 512, START = 770, STOP = 791 };
int main (int argc, char **argv) {
char buf[MAXC] = ""; /* line buffer */
/* open file (or read from stdin -- default) */
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
if (!fp) { /* validate file open for reading */
fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
return 1;
}
while (fgets (buf, MAXC, fp)) { /* read each line */
int val; /* 1st col value */
size_t len = strlen (buf); /* get buf len for validation */
char *p, *delim = " \t\n"; /* pointer & delimiters */
if (len && buf[len - 1] != '\n') { /* validate complete line */
fprintf (stderr, "error: line exceeds %d chars.\n", MAXC);
return 1;
}
p = strtok (buf, delim); /* parse 1st column (as string) */
if (p == NULL) { /* handle 1st col error */
fprintf (stderr, "error: parse of first column failed.\n");
return 1;
}
errno = 0;
val = (int)strtol (p, NULL, BASE); /* convert to long/int */
if (errno) {
fprintf (stderr, "error: strtol() conversion failed.\n");
return 1;
}
/* for each line between START & STOP (inclusive) */
if (START <= val && val <= STOP) {
printf ("%d", val); /* output 1st col */
/* tokenize line, remove 2nd column, append 1 at end */
p = strtok (NULL, delim); /* parse/discard 2nd column */
if (!p) { /* handle failure to parse 2nd column */ }
p = strtok (NULL, delim); /* parse 3rd column */
if (!p) { /* handle failure to parse 3rd column */ }
while (p) { /* while token read */
printf (" %-8s", p); /* print token */
p = strtok (NULL, delim); /* parse next token/column */
}
printf ("1\n"); /* print final 1 at end */
}
}
if (fp != stdin) fclose (fp); /* close file if not stdin */
return 0;
}
$ ./bin/parsecol <dat/columns.txt
770 1372 1373 1
771 1373 1374 1
772 1375 1376 1
773 1376 1377 1
774 1377 1378 1
775 1378 1379 1
776 1379 1380 1
777 1380 1381 1
778 1381 1382 1
779 1382 1383 1
780 1383 1384 1
781 1384 1385 1
782 1386 1387 1
783 1387 1388 1
784 1388 1389 1
785 1389 1390 1
786 1390 1391 1
787 1391 1392 1
788 1392 1393 1
789 1393 1394 1
790 1394 1395 1
791 1395 1396 1
#include <stdio.h>
#include <string.h>
/* constants for max chars, start & stop values */
enum { MAXC = 512, START = 770, STOP = 791 };
int main (int argc, char **argv) {
char buf[MAXC] = ""; /* line buffer */
/* open file (or read from stdin -- default) */
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
if (!fp) { /* validate file open for reading */
fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
return 1;
}
while (fgets (buf, MAXC, fp)) { /* read each line */
int val; /* 1st col value */
size_t len = strlen (buf); /* get buf len for validation */
char *p, *delim = " \t\n"; /* pointer & delimiters */
if (len && buf[len - 1] != '\n') { /* validate complete line */
fprintf (stderr, "error: line exceeds %d chars.\n", MAXC);
return 1;
}
if (sscanf (buf, "%d", &val) != 1) { /* convert 1st col to int */
fprintf (stderr, "error: conversion failure column 1.\n");
return 1;
}
/* for each line between START & STOP (inclusive) */
if (START <= val && val <= STOP) {
/* tokenize line, remove 2nd column, append 1 at end */
p = strtok (buf, delim); /* parse 1st column */
if (p == NULL) { /* handle 1st col error */
fprintf (stderr, "error: parse of first column failed.\n");
return 1;
}
printf ("%s", p); /* print column 1 */
p = strtok (NULL, delim); /* parse/discard 2nd column */
if (!p) { /* handle failure to parse 2nd column */ }
p = strtok (NULL, delim); /* parse 3rd column */
if (!p) { /* handle failure to parse 3rd column */ }
while (p) { /* while token read */
printf (" %-8s", p); /* print token */
p = strtok (NULL, delim); /* parse next token/column */
}
printf ("1\n"); /* print final 1 at end */
}
}
if (fp != stdin) fclose (fp); /* close file if not stdin */
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
/* constants for max chars, start & stop values */
enum { BASE = 10, MAXC = 512, START = 770, STOP = 791 };
int parsecolumns (FILE *fp);
int main (void) {
char filename[MAXC] = "";
FILE *fp = NULL;
for (;;) { /* loop until good filename provided (or canceled) */
int rtn; /* always capture and validate scanf return */
printf ("enter filename: ");
if ((rtn = scanf ("%s", filename)) != 1) {
if (rtn == EOF) {
fprintf (stderr, " user canceled input.\n");
return 1;
}
}
else {
fp = fopen (filename, "r");
if (!fp) /* validate file open for reading */
fprintf (stderr, "error: file open failed. '%s'.\n", filename);
else
break;
}
}
if (parsecolumns (fp)) { /* parse columns in file */
fprintf (stderr, "error: failure in parsecolumns()\n");
}
if (fp != stdin) fclose (fp); /* close file if not stdin */
return 0;
}
int parsecolumns (FILE *fp)
{
char buf[MAXC] = ""; /* line buffer */
if (!fp) { /* validate file open for reading */
fprintf (stderr, "error: invalid file parameter 'fp'.\n");
return 1;
}
while (fgets (buf, MAXC, fp)) { /* read each line */
int val; /* 1st col value */
size_t len = strlen (buf); /* get buf len for validation */
char *p, *delim = " \t\n"; /* pointer & delimiters */
if (len && buf[len - 1] != '\n') { /* validate complete line */
fprintf (stderr, "error: line exceeds %d chars.\n", MAXC);
return 1;
}
p = strtok (buf, delim); /* parse 1st column (as string) */
if (p == NULL) { /* handle 1st col error */
fprintf (stderr, "error: parse of first column failed.\n");
return 1;
}
errno = 0;
val = (int)strtol (p, NULL, BASE); /* convert to long/int */
if (errno) {
fprintf (stderr, "error: strtol() conversion failed.\n");
return 1;
}
/* for each line between START & STOP (inclusive) */
if (START <= val && val <= STOP) {
printf ("%d", val); /* output 1st col */
/* tokenize line, remove 2nd column, append 1 at end */
p = strtok (NULL, delim); /* parse/discard 2nd column */
if (!p) { /* handle failure to parse 2nd column */ }
p = strtok (NULL, delim); /* parse 3rd column */
if (!p) { /* handle failure to parse 3rd column */ }
while (p) { /* while token read */
printf (" %-8s", p); /* print token */
p = strtok (NULL, delim); /* parse next token/column */
}
printf ("1\n"); /* print final 1 at end */
}
}
return 0;
}