C - 从文本文件读取输入 (int,string,int,int)
C - Read input from text file (int,string,int,int)
首先,对于任何英文错误,我们深表歉意。
所以,我在 .txt 文件中有这些数据
Codigo,Produto,StockMinimo,StockAtual
1,Couro,300,1000
2,Tecido,250,2000
...
我想跳过第一行,只将整数读入结构
我正在使用波纹管函数来计算文件的行数:
int nrLinhasFicheiro(char *filename){
char ch;
FILE *file;
file = fopen(filename, "r");
int linhas = 0;
if (file != NULL) {
for (ch = getc(file); ch != EOF; ch = getc(file))
if (ch == '\n')
linhas = linhas + 1;
}
fclose(file);
return linhas - 1;
}
而这个将文件读取到结构“Stock”:
void carregarStock(Stock *stock, char *nomeFicheiro){
int i = 0;
int codigo; //stores "codigo" values
char stringFake[40], *storeProduto; //variables to store first line and "Produto" string
int minimo, quantidade;
FILE *fp = fopen(nomeFicheiro, "r");
int numeroLinhas = nrLinhasFicheiro(nomeFicheiro);
if (fp != NULL){
if(numeroLinhas >0){
fscanf(fp, "%s",stringFake);//skip first line
while(i< numeroLinhas){
fscanf(fp, "%d,%s ,%d,%d", &codigo, storeProduto, &minimo, &quantidade);
//fscanf(fp, "%d,%s %d,%d", &codigo, storeProduto, &minimo, &quantidade); also tried this and don't work
if(codigo==1){
stock->minStockCouro = minimo;
stock->couroStock = quantidade;
}else if(codigo==2){
stock->minStockTecido = minimo;
stock->tecidoStock = quantidade;
}else if(codigo==3){
stock->minStockBorracha = minimo;
stock->borrachaStock = quantidade;
}else if(codigo==4){
stock->minStockCordoes = minimo;
stock->cordoesStock = quantidade;
}else if(codigo==5){
stock->minStockPalmilhas = minimo;
stock->palmilhasStock = quantidade;
}
i++;
}
}else{
puts("Error");
}
}else{
puts(MSG_ERRO_LER_FICHEIRO);
}
fclose(fp);
}
打印结构的函数:
void mostrarStock(Stock stock){
puts("============== Stock : =============\n");
puts("Codigo | Produto | Stock Minimo | Stock Atual\n");
printf("1\tCouro\t\t%d\t\t%d\n", stock.minStockCouro, stock.couroStock);
printf("2\tTecido\t\t%d\t\t%d\n", stock.minStockTecido, stock.tecidoStock);
printf("3\tBorracha\t%d\t\t%d\n", stock.minStockBorracha, stock.borrachaStock);
printf("4\tCordões\t\t%d\t\t%d\n", stock.minStockCordoes, stock.cordoesStock);
printf("5\tPalmilhas\t%d\t\t%d\n", stock.minStockPalmilhas, stock.palmilhasStock);
}
这就是我在 main 中调用函数的方式:
int main(int argc, char** argv) {
char *nomeFicheiro1 = "tabela_stocks.txt";
Stock stock;
carregarStock(&stock, nomeFicheiro1);
mostrarStock(stock);
return (EXIT_SUCCESS);
}
打印结构的函数不打印。
我猜错误在
fscanf(fp, "%d,%s ,%d,%d", &codigo, storeProduto, &minimo, &quantidade);
我做错了什么?
您可以创建一个辅助函数来从一行中读出两个整数。
bool get_two(FILE *stream, int* a, int* b) {
return fscanf(stream, " %*[^,],%*[^,],%d,%d", a, b) == 2;
}
然后你只需要调用它 5 次。
示例:
#include <stdbool.h>
#include <stdio.h>
typedef struct {
int couroStock;
int minStockCouro;
int tecidoStock;
int minStockTecido;
int borrachaStock;
int minStockBorracha;
int cordoesStock;
int minStockCordoes;
int palmilhasStock;
int minStockPalmilhas;
} Stock;
bool get_two(FILE *stream, int* a, int* b) {
return fscanf(stream, " %*[^,],%*[^,],%d,%d", a, b) == 2;
}
int main() {
FILE *fp = fopen("tabela_stocks.txt", "r");
if(fp) {
Stock s;
fscanf(fp, "%*[^\n]"); // skip first line
if(get_two(fp, &s.couroStock, &s.minStockCouro) &&
get_two(fp, &s.tecidoStock, &s.minStockTecido) &&
get_two(fp, &s.borrachaStock, &s.minStockBorracha) &&
get_two(fp, &s.cordoesStock, &s.minStockCordoes) &&
get_two(fp, &s.palmilhasStock, &s.minStockPalmilhas))
{
printf("%d %d\n", s.couroStock, s.minStockCouro);
printf("%d %d\n", s.tecidoStock, s.minStockTecido);
printf("%d %d\n", s.borrachaStock, s.minStockBorracha);
printf("%d %d\n", s.cordoesStock, s.minStockCordoes);
printf("%d %d\n", s.couroStock, s.minStockCouro);
}
fclose(fp);
}
}
如果tabela_stocks.txt
包含
Codigo,Produto,StockMinimo,StockAtual
1,Couro,300,1000
2,Tecido,250,2000
3,Borracha,200,500
4,Cordões,500,2000
5,Palmilhas,500,1000
那么输出将是
300 1000
250 2000
200 500
500 2000
300 1000
由于您的 Stock
struct
中的不同股票之间有很多相似之处,您可以将其分解成更小的部分并制作一个 struct
仅包含有关 一个 存货:
#include <stdbool.h>
#include <stdio.h>
typedef struct {
int stock;
int min_stock;
} Stock;
bool Stock_read(FILE *stream, Stock *s) {
return fscanf(stream, " %*[^,],%*[^,],%d,%d", &s->stock, &s->min_stock) == 2;
}
void Stock_print(const Stock *s) {
printf("%d %d\n", s->stock, s->min_stock);
}
这样你就可以创建一个 Stocks
类型:
typedef struct {
Stock Couro;
Stock Tecido;
Stock Borracha;
Stock Cordoes;
Stock Palmilhas;
} Stocks;
bool Stocks_read(FILE *stream, Stocks *s) {
return
Stock_read(stream, &s->Couro) &&
Stock_read(stream, &s->Tecido) &&
Stock_read(stream, &s->Borracha) &&
Stock_read(stream, &s->Cordoes) &&
Stock_read(stream, &s->Palmilhas);
}
void Stocks_print(const Stocks *s) {
Stock_print(&s->Couro);
Stock_print(&s->Tecido);
Stock_print(&s->Borracha);
Stock_print(&s->Cordoes);
Stock_print(&s->Palmilhas);
}
阅读和打印会变得更简单:
int main() {
FILE *fp = fopen("tabela_stocks.txt", "r");
if(fp) {
Stocks s;
fscanf(fp, "%*[^\n]"); // skip first line
if(Stocks_read(fp, &s)) {
Stocks_print(&s);
}
fclose(fp);
}
}
仔细观察 Stocks
struct
您可能需要考虑改用数组:
typedef struct {
Stock stocks[5];
} Stocks;
这也将简化其余代码,因为您可以遍历该数组以读取和打印每个 Stock
.
首先,对于任何英文错误,我们深表歉意。 所以,我在 .txt 文件中有这些数据
Codigo,Produto,StockMinimo,StockAtual
1,Couro,300,1000
2,Tecido,250,2000
...
我想跳过第一行,只将整数读入结构
我正在使用波纹管函数来计算文件的行数:
int nrLinhasFicheiro(char *filename){
char ch;
FILE *file;
file = fopen(filename, "r");
int linhas = 0;
if (file != NULL) {
for (ch = getc(file); ch != EOF; ch = getc(file))
if (ch == '\n')
linhas = linhas + 1;
}
fclose(file);
return linhas - 1;
}
而这个将文件读取到结构“Stock”:
void carregarStock(Stock *stock, char *nomeFicheiro){
int i = 0;
int codigo; //stores "codigo" values
char stringFake[40], *storeProduto; //variables to store first line and "Produto" string
int minimo, quantidade;
FILE *fp = fopen(nomeFicheiro, "r");
int numeroLinhas = nrLinhasFicheiro(nomeFicheiro);
if (fp != NULL){
if(numeroLinhas >0){
fscanf(fp, "%s",stringFake);//skip first line
while(i< numeroLinhas){
fscanf(fp, "%d,%s ,%d,%d", &codigo, storeProduto, &minimo, &quantidade);
//fscanf(fp, "%d,%s %d,%d", &codigo, storeProduto, &minimo, &quantidade); also tried this and don't work
if(codigo==1){
stock->minStockCouro = minimo;
stock->couroStock = quantidade;
}else if(codigo==2){
stock->minStockTecido = minimo;
stock->tecidoStock = quantidade;
}else if(codigo==3){
stock->minStockBorracha = minimo;
stock->borrachaStock = quantidade;
}else if(codigo==4){
stock->minStockCordoes = minimo;
stock->cordoesStock = quantidade;
}else if(codigo==5){
stock->minStockPalmilhas = minimo;
stock->palmilhasStock = quantidade;
}
i++;
}
}else{
puts("Error");
}
}else{
puts(MSG_ERRO_LER_FICHEIRO);
}
fclose(fp);
}
打印结构的函数:
void mostrarStock(Stock stock){
puts("============== Stock : =============\n");
puts("Codigo | Produto | Stock Minimo | Stock Atual\n");
printf("1\tCouro\t\t%d\t\t%d\n", stock.minStockCouro, stock.couroStock);
printf("2\tTecido\t\t%d\t\t%d\n", stock.minStockTecido, stock.tecidoStock);
printf("3\tBorracha\t%d\t\t%d\n", stock.minStockBorracha, stock.borrachaStock);
printf("4\tCordões\t\t%d\t\t%d\n", stock.minStockCordoes, stock.cordoesStock);
printf("5\tPalmilhas\t%d\t\t%d\n", stock.minStockPalmilhas, stock.palmilhasStock);
}
这就是我在 main 中调用函数的方式:
int main(int argc, char** argv) {
char *nomeFicheiro1 = "tabela_stocks.txt";
Stock stock;
carregarStock(&stock, nomeFicheiro1);
mostrarStock(stock);
return (EXIT_SUCCESS);
}
打印结构的函数不打印。 我猜错误在
fscanf(fp, "%d,%s ,%d,%d", &codigo, storeProduto, &minimo, &quantidade);
我做错了什么?
您可以创建一个辅助函数来从一行中读出两个整数。
bool get_two(FILE *stream, int* a, int* b) {
return fscanf(stream, " %*[^,],%*[^,],%d,%d", a, b) == 2;
}
然后你只需要调用它 5 次。
示例:
#include <stdbool.h>
#include <stdio.h>
typedef struct {
int couroStock;
int minStockCouro;
int tecidoStock;
int minStockTecido;
int borrachaStock;
int minStockBorracha;
int cordoesStock;
int minStockCordoes;
int palmilhasStock;
int minStockPalmilhas;
} Stock;
bool get_two(FILE *stream, int* a, int* b) {
return fscanf(stream, " %*[^,],%*[^,],%d,%d", a, b) == 2;
}
int main() {
FILE *fp = fopen("tabela_stocks.txt", "r");
if(fp) {
Stock s;
fscanf(fp, "%*[^\n]"); // skip first line
if(get_two(fp, &s.couroStock, &s.minStockCouro) &&
get_two(fp, &s.tecidoStock, &s.minStockTecido) &&
get_two(fp, &s.borrachaStock, &s.minStockBorracha) &&
get_two(fp, &s.cordoesStock, &s.minStockCordoes) &&
get_two(fp, &s.palmilhasStock, &s.minStockPalmilhas))
{
printf("%d %d\n", s.couroStock, s.minStockCouro);
printf("%d %d\n", s.tecidoStock, s.minStockTecido);
printf("%d %d\n", s.borrachaStock, s.minStockBorracha);
printf("%d %d\n", s.cordoesStock, s.minStockCordoes);
printf("%d %d\n", s.couroStock, s.minStockCouro);
}
fclose(fp);
}
}
如果tabela_stocks.txt
包含
Codigo,Produto,StockMinimo,StockAtual
1,Couro,300,1000
2,Tecido,250,2000
3,Borracha,200,500
4,Cordões,500,2000
5,Palmilhas,500,1000
那么输出将是
300 1000
250 2000
200 500
500 2000
300 1000
由于您的 Stock
struct
中的不同股票之间有很多相似之处,您可以将其分解成更小的部分并制作一个 struct
仅包含有关 一个 存货:
#include <stdbool.h>
#include <stdio.h>
typedef struct {
int stock;
int min_stock;
} Stock;
bool Stock_read(FILE *stream, Stock *s) {
return fscanf(stream, " %*[^,],%*[^,],%d,%d", &s->stock, &s->min_stock) == 2;
}
void Stock_print(const Stock *s) {
printf("%d %d\n", s->stock, s->min_stock);
}
这样你就可以创建一个 Stocks
类型:
typedef struct {
Stock Couro;
Stock Tecido;
Stock Borracha;
Stock Cordoes;
Stock Palmilhas;
} Stocks;
bool Stocks_read(FILE *stream, Stocks *s) {
return
Stock_read(stream, &s->Couro) &&
Stock_read(stream, &s->Tecido) &&
Stock_read(stream, &s->Borracha) &&
Stock_read(stream, &s->Cordoes) &&
Stock_read(stream, &s->Palmilhas);
}
void Stocks_print(const Stocks *s) {
Stock_print(&s->Couro);
Stock_print(&s->Tecido);
Stock_print(&s->Borracha);
Stock_print(&s->Cordoes);
Stock_print(&s->Palmilhas);
}
阅读和打印会变得更简单:
int main() {
FILE *fp = fopen("tabela_stocks.txt", "r");
if(fp) {
Stocks s;
fscanf(fp, "%*[^\n]"); // skip first line
if(Stocks_read(fp, &s)) {
Stocks_print(&s);
}
fclose(fp);
}
}
仔细观察 Stocks
struct
您可能需要考虑改用数组:
typedef struct {
Stock stocks[5];
} Stocks;
这也将简化其余代码,因为您可以遍历该数组以读取和打印每个 Stock
.