I'm trying to make a loop where my "soft" variable is taking the value of my other variable.
I'm trying to put each words of my file text (country-name, an espace, capital-of-country) in table.
But I can't find how to do it...
There's my program (partly) :
int main(){
FILE *Africa;
FILE *America;
FILE *Asia;
FILE *Europe;
FILE *Oceania;
int countryIndex = 0;
int capitalIndex;
char countryTable[15][30];
char capitalTable[15][30];
//FILE country[] = {Africa, America, Asia, Europe, Oceania};
Africa = fopen("Africa.txt", "r");
America = fopen("America.txt", "r");
Asia = fopen("Asia.txt", "r");
Europe = fopen("Europe.txt", "r");
Oceania = fopen("Oceania.txt", "r");
if (Africa == NULL || America == NULL || Asia == NULL || Europe == NULL || Oceania == NULL){
printf("Error, failed when trying to open the continent file.\n");
return 1;
}
for (FILE *country = {Africa, America, Asia, Europe, Oceania}){
while (fscanf(country, "%s", countryTable[countryIndex]) != EOF){
fscanf(country,"%s", capitalTable[countryIndex]);
countryIndex++;
}
for (capitalIndex = 0; capitalIndex < countryIndex; capitalIndex++){
printf("Country : %s - ", countryTable[capitalIndex]);
printf("Capital : %s\n", capitalTable[capitalIndex]);
}
}
/*while (fscanf(Africa, "%s", countryTable[countryIndex]) != EOF){
fscanf(Africa,"%s", capitalTable[countryIndex]);
countryIndex++;
}
for (capitalIndex = 0; capitalIndex < countryIndex; capitalIndex++){
printf("Country : %s - ", countryTable[capitalIndex]);
printf("Capital : %s\n", capitalTable[capitalIndex]);
}*/
fclose(Africa);
fclose(America);
fclose(Asia);
fclose(Europe);
fclose(Oceania);
return 0;
}
If you need additional information do not hesitate.
I found a solution, even if it's not the way I wanted to do it. By modifying my code like this :
int main(){
char *continentName[] = {"Africa.txt", "America.txt", "Asia.txt", "Europe.txt", "Oceania.txt"};
int nbrContinent = sizeof continentName / sizeof continentName[0];
int countryIndex = 0;
int capitalIndex;
char countryTable[15][30];
char capitalTable[15][30];
for (int i = 0; i < nbrContinent; i++){
FILE *continent = fopen(continentName[i], "r");
if (continent == NULL){
printf("Error, failed when trying to open the continent file.\n");
return 1;
}
while (fscanf(continent, "%s", countryTable[countryIndex]) != EOF){
fscanf(continent,"%s", capitalTable[countryIndex]);
countryIndex++;
}
fclose(continent);
}
for (capitalIndex = 0; capitalIndex < countryIndex; capitalIndex++){
printf("Country : %s - ", countryTable[capitalIndex]);
printf("Capital : %s\n", capitalTable[capitalIndex]);
}
return 0;
}
This way it's easier and I get around the problem haha.
By doing so, each capital name is associated with its country in the tables. e.g. tabContinent[1] -> tabCountry[1]
I just put the retrieval of each word in my files in the initial for loop so that I don't have to redo one. To do this, I changed the type of my "FILE" variables into an array of chars that directly contains the names of the files in question. Then you have to be careful to close the files at the end of the loop but inside (otherwise the function doesn't end correctly and can cause problems when calling another function). And finally, add a for loop outside the first one (otherwise the values of the arrays are displayed each time the files are read) in order to enter the data retrieved in the arrays.
Related
I have an issue with a CSV writing function, some times it prints a blank line to the file. How do I check for this or remove it as I dont want to write a blank line to the CSV.
My CSV output is:
As you can see the first 2 lines are correct the third is an error
After some time it recovers and the extra lines are removed.
Here is my Write function to the CSV:
void Write_block_to_sd_card()
{
while (fno.fname[0]);
ff_result = f_open(&file, FILE_NAME, FA_READ | FA_WRITE | FA_OPEN_APPEND);
if(ff_result != FR_OK)//Not passing if the file is missing
{
if (ff_result != FR_OK)
{
NRF_LOG_INFO("Unable to open or create file: " FILE_NAME ".");
SD_CARD_PRESENT = 0;
return;
}
}
else//File was openned fine
{
NRF_LOG_RAW_INFO("");
NRF_LOG_INFO("Writing to file as a block " FILE_NAME "...");
SD_CARD_PRESENT = 1;
//File is opened
for(int i = 0; i<MAXIMUM_BUFFER_STORAGE;i ++)
{
char buffer[50];//Buffer to hold output
char stT1 [MAX_BUFFER_SIZE];//T1
char stT2 [MAX_BUFFER_SIZE];//T2
char stT3 [MAX_BUFFER_SIZE];//T3
char stT4 [MAX_BUFFER_SIZE];//T4
char stPd [MAX_BUFFER_SIZE];//Pdiff
char stUT [MAX_BUFFER_SIZE];//Unix time
sprintf(stT1, "%d", SD_CARD_T1[i]);
sprintf(stT2, "%d", SD_CARD_T2[i]);
sprintf(stT3, "%d", SD_CARD_T3[i]);
sprintf(stT4, "%d", SD_CARD_T4[i]);
sprintf(stPd, "%f", SD_CARD_Pdiff[i]);
sprintf(stUT, "%d", SD_CARD_UNIX_TIME[i]);
//Do not write the ID to the SD card only chuck over the Unix time
snprintf(buffer, sizeof buffer, "%s,%s,%s,%s,%s,%s\r\n",stUT,stT1,stT2,stT3,stT4,stPd);//Convert to a string
if (strcmp(buffer, "") != 0)//Not null
{
if((SD_CARD_T1[i] != 0) && (SD_CARD_T2[i] != 0) && (SD_CARD_T3[i] != 0) && (SD_CARD_T4[i] != 0))//Null check
//Need to always write the correct length of data
ff_result = f_write(&file, buffer, sizeof(buffer), (UINT *) &bytes_written);//Add the input data to the CSV file
if (ff_result != FR_OK)
{
NRF_LOG_INFO("Write failed\r\n.");
}
else
{
}
}
ID = ID + 1;//Increment the ID counter
}
NRF_LOG_INFO("Write new entry %d bytes written.", (bytes_written*(MAXIMUM_BUFFER_STORAGE)));
}
(void) f_close(&file);
Time_stamp_id = ID;//Set the time stamp id to the latest value.
return;
}
I have a set of internal char arrays which store the data values to write to the CSV, I simply loop them and store to the SD card. But, I need to not create the blank lines.
I'm trying to get better at coding in general and C in particular, and am coding a small text adventure game. I read a string input by the user i.e LOOK room and compare it to a txt file with the list of commands for that particular section.
As I am reading from the text file I have a counter which keeps track of which line is being read, when the match is made I convert the line number to a character and concatenate it to "outside.txt" so that when the correct command is input it will read from the correct file i.e LOOK room would load text from 1outside.txt etc.
However, when inputting anything it just loops on "I dont understand" forever. Any explanation as to why or constructive comments on my code are appreciated, especially if I am misunderstanding how files and/or strings in c.
int mansionOutside(void)
{
int stop = 1;
char choice[25];
char word_match[25];
char text_line[73];
char line1[25];
char temp[2];
int counter;
FILE *fptr;
fptr = fopen("mansion_commands.txt", "r");
if (fptr == NULL)
{
printf("ERROR!");
}
else
{
while (stop == 1)
{
printf("\n");
fgets(choice, sizeof choice, stdin);
while (fgets (line1, 25, fptr)!= NULL)
{
if (strcmp(line1, choice) == 0)
{
printf("%s\n", line1);
stop = 0;
break;
}
else
{
counter++;
printf("%s + %s\n", line1, choice);
}
}
if (stop == 1)
{
printf("I dont understand\n");
counter = 1;
}
}
fclose(fptr);
counter = counter + '0';
temp[0] = counter;
temp[1] = '\0';
strncat(word_match, temp , 1);
strcat(word_match, ".txt");
fptr = fopen(word_match, "r");
if (fptr == NULL)
{
printf("ERROR!\n");
}
else
{
printf("Debugging : File opened Successfully\n");
while (fgets (text_line, 72, fptr) != NULL)
{
printf("%s", text_line);
//delay(2);
}
}
}
}
EDIT : Took in suggestions for improvements to avoid Buffer overflows such as using > fgets , but I think there is something I have missed. Now If I input anything contained in the file, it works fine. If however I input something wrong, then something correct on re-prompt, It skips the inner while loop all together and goes straight to "I don't understand".
The following is what happens when my input is LOOK room, and then LOOK mansion.
The following function is only used to display certain areas of a file. In this case I am trying to copy every line that has the word "EMPTY" from the main file to another file. Other than by opening a file to write to I use for char arrays to look for the proper string needed. At this point, I try to use the data from that file(In which the string was searched for) and try to copy it into another file. At this point some of the new file prints to the screen which is the first part at the top under where I created the file but when I try to add the string from the other file they do no print. Can you print certain string fro one file to another?
void emptySeats(void)
{
int position = 0;
int AvalabileOne = 0;
int countGone = 0;
int confirm = 0;
char testOne[] = "EMPTY";
char StrOne[10], StrTwo[10], StrThree[10], StrFour[10];
FILE *fEmptyseatArrangement;
fEmptyseatArrangement = fopen("airlineEmptySeatingArrangment.txt", "w+");
fprintf(fseatArrangement, "\t\t\tEcono-Airlines Passangers System\n\n\t Seat Number\t Seatavalability Last Name First Name\n");
do
{
fseatArrangement = fopen("airlineSeatingArrangment.txt", "r");
fseek(fseatArrangement, 102, SEEK_SET);
while (AvalabileOne < FULL)
{
fscanf(fseatArrangement, "%s%s%s%s\n", &StrOne, &StrTwo, &StrThree, &StrFour);
if (strcmp(StrThree, testOne))
{
fprintf(fEmptyseatArrangement, "\t\t%s\t\t%s\t\t%s\t\t%s\n", StrOne, StrTwo, StrThree, StrFour);
countGone = countGone + 1;
}
AvalabileOne = AvalabileOne + 1;
}
fclose(fEmptyseatArrangement);
fclose(fseatArrangement);
fEmptyseatArrangement = fopen("airlineEmptySeatingArrangment.txt", "r");
while (fgets(econoAirEmptySeatArrangement, 1000, fEmptyseatArrangement) != NULL)
printf("%s", econoAirEmptySeatArrangement);
fclose(fEmptyseatArrangement);
printf("There are %d seats vacant at the moment\n", FULL - countGone);
printf("Enter Zero(0) Key to return to menu at anytime.");
scanf(" %d", &position);
if (position == 0)
{
system("cls");
menu();
}
else
{
system("cls");
printf("INVALID INPUT! Please try again.\n");
}
} while (AvalabileOne != 0);
system("pause");
return;
}
I'm trying to make a sort of a database program and ran into a few issues with reading integers from a text file in C.
I have the following code:
#include <stdio.h>
int main(){
int index;
FILE * fp;
if((fp = fopen("read_file.txt","r+")) == NULL){
perror("Cannot open file");
printf("\nCreating new file...");
if((fp = fopen("read_file.txt","w+")) == NULL){
perror("\nCannot create file.. Terminating..");
return -1;
}
}
fputs("INDEX = 3",fp);
fscanf(fp, "INDEX = %d",&index);
printf("index = %d\n",index);
fclose(fp);
return 0;
}
When i try to run the program it outputs "index = 16", i tried using fgets and sscanf but same thing happens. With strings however it decides to print out a bunch of characters that don't make sense.
What you see in undefined behavior because you write a string to the file and try to scan INDEX = %d which is not there in the file because of the file pointer is pointing after INDEX = 3
You need to rewind(fp) before scanning.
fputs("INDEX = 3",fp);
rewind(fp);
if( fscanf(fp, "INDEX = %d",&index) != 1)
printf("Scanning failes\n");
else
printf("INDEX = %d\n",index);
This is for a beginner's C programming unit. I'm trying to read a text file containing MAC addresses and the data they received, separate out the relevant data (address and number of packets), copy the addresses to an array without repeating any of them and sum the associated number of packets if an identical address is encountered.
I can read the file in just fine, and get the bits of each line I want without issue, but when I try to check each address read against those already in the array I hit a problem. Depending on the location of the integer counting the number of full lines, the program either fails to recognise identical strings and prints them all as they are in the file, or prints them over one another in addresses[0], leaving me with only the last address. I'm stumped and need some fresh eyes on this - any suggestions would be greatly appreciated.
My code follows:
static void readadds(char filename[])
{
FILE* packetfile = fopen(filename, "r");
FILE* datafile = fopen("packdata.txt", "w+");
// Open file from input; create temporary file to store sorted data.
char line[100];
char addresses[500][18];
int datasize[500];
int addressno = 0;
// Create storage for lines read from text file, addresses and related data.
if(packetfile != NULL)
{
while(fgets(line, sizeof line, packetfile) != NULL)
{
int linenum = 0;
char thisadd[18];
int thisdata;
//Create arrays to temp store data from each line
sscanf(line, "%*s %*s %s %i", thisadd, &thisdata);
for(int i = 0; i < 500; i++)
{
if(strcmp(thisadd, addresses[i]) == 0)
{ //check if the address is already in the array
int x = datasize[i];
datasize[i] = x + thisdata; //sum packet data if address already exists
printf("Match!\n");
break;
}
else
{
strcpy(addresses[linenum], thisadd); //initialize new address
datasize[linenum] = thisdata; //initialize assoc. data
linenum++;
addressno++;
printf("Started!\n");
break;
}
}
}
for(int i = 0; i <= addressno; i++)
{
printf("%s %i\n", addresses[i], datasize[i]);
fprintf(datafile,"%s %i\n", addresses[i], datasize[i]);
}
}
fclose(packetfile);
fclose(datafile);
}
This version prints over addresses[0]. If linenum is replaced by addressno in the for() loop, identical strings are not recognised. My dataset is arranged like this:
1378251369.691375 84:1b:5e:a8:bf:7f 68:94:23:4b:e8:35 100
1378251374.195670 00:8e:f2:c0:13:cc 00:11:d9:20:aa:4e 397
1378251374.205047 00:8e:f2:c0:13:cc 00:11:d9:20:aa:4e 397
1378251374.551604 00:8e:f2:c0:13:cc 00:11:d9:20:aa:4e 157
1378251375.551618 84:1b:5e:a8:bf:7c cc:3a:61:df:4b:61 37
1378251375.552697 84:1b:5e:a8:bf:7c cc:3a:61:df:4b:61 37
1378251375.553957 84:1b:5e:a8:bf:7c cc:3a:61:df:4b:61 37
1378251375.555332 84:1b:5e:a8:bf:7c cc:3a:61:df:4b:61 37
I'm almost certain this is what you're trying to do. The logic to add a new entry was incorrect. You only add one if you have exhausted searching all the current ones, which means you need to finish the current for-search before the add.
Note: Not tested for compilation, but hopefully you get the idea.
static void readadds(char filename[])
{
// Open file from input; create temporary file to store sorted data.
FILE* packetfile = fopen(filename, "r");
FILE* datafile = fopen("packdata.txt", "w+");
// Create storage for lines read from text file, addresses and related data.
char addresses[500][18];
int datasize[500];
int addressno = 0;
if (packetfile != NULL)
{
char line[100];
while(fgets(line, sizeof line, packetfile) != NULL)
{
char thisadd[18];
int thisdata = 0;
//Create arrays to temp store data from each line
if (sscanf(line, "%*s %*s %s %i", thisadd, &thisdata) == 2)
{
// try to find matching address
for(int i = 0; i < addressno; i++)
{
if(strcmp(thisadd, addresses[i]) == 0)
{
//check if the address is already in the array
datasize[i] += thisdata;;
printf("Match!\n");
break;
}
}
// reaching addressno means no match. so add it.
if (i == addressno)
{
printf("Started!\n");
strcpy(addresses[addressno], thisadd); //initialize new address
datasize[addressno++] = thisdata; //initialize assoc. data
}
}
else
{ // failed to parse input parameters.
break;
}
}
for(int i = 0; i <= addressno; i++)
{
printf("%s %i\n", addresses[i], datasize[i]);
fprintf(datafile,"%s %i\n", addresses[i], datasize[i]);
}
}
fclose(packetfile);
fclose(datafile);
}