I'm developing some code in C that reads a file extension and stores it as a code in a byte together whether a text file or binary file is being processed. Later I wish to recover the file extension that is encoded in a byte.
As a test I created a loop in the main function where I can test out the function fileExtenCode(), which is in the second listing.
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#define EXLEN 9
#define EXNUM 8
typedef unsigned char BYTE;
bool fileExtenCode(char*, BYTE*, int*);
int main(void) {
char fileExten[EXLEN];
BYTE code;
int bin;
for (;;) {
printf("Type file extension: ");
scanf_s("%s", fileExten, EXLEN);
if (fileExten[0] == '.') break;
printf("%s\n", fileExten);
code = 0;
bin = 0;
bool extFound = fileExtenCode(fileExten, &code, &bin); // <== (1)
if (extFound) printf("Extension found: TRUE\n");
else printf("Extension found: FALSE\n");
printf("%s%d", "Code: ", code);
if (bin) printf(" binary file\n");
else printf(" text file\n");
printf("\n");
printf("Type code: ");
int icode;
scanf_s("%d", &icode);
code = icode;
bin = -1;
fileExtenCode(fileExten, &code, &bin); // <== (2)
printf("%s", fileExten); // <== (5)
printf("\n");
}
return 0;
}
The function that I'm trying to test is as follows:
bool fileExtenCode(char* ext, BYTE* code, int* binary) {
char *fileEx[EXNUM] = {
"jpg1", "txt0", "html0", "xml0", "exe1", "bmp1", "gif1", "png1"};
if (*binary < 0) { // <== (3)
ext = fileEx[*code]; // <== (4)
return true;
}
size_t extLen = strlen(ext);
for (BYTE i = 0; i < EXNUM; i++) {
if (strncmp(fileEx[i], ext, extLen) == 0) {
*binary = (fileEx[i][extLen] == '1') ? 1 : 0;
*code = i;
return true;
}
}
return false;
}
The idea is that you pass a string with the file extension to fileExtenCode() in statement (1) in main, and the function searched for that extension in an array, and if found returns true together with the code argument indicating the position in array of file extensions and the binary flag as 0 or 1 indicating if the file is text or binary. A '0' or '1' immediately follows file extension in the array. If the extension is not found, the function returns with false and the return values in the arguments have no meaning.
So far so good, and this part works correctly. However, in using the function in reverse to recover the file extension given the input value of code, it fails when called with statement (2) in main. In this case binary is set to -1, and then the function is called and the condition at (3) is now true and ext in (4) recovers the file extension. This is confirmed when inserting a temporary print statement immediately after (4), but this value is not returned in (5) back in main, and an old input value is instead printed.
Obviously there is a problem with pointers, but I cannot see an obvious way of fixing it. My question is how to correct this without messing up the rest of the code, which is working correctly? Note that char* ext and BYTE* code are used for both input and output, whilst int* binary is used as an input flag and returns no useful value when set to -1.
Once this problem is fixed, then it should be relatively easy to separate the binary flag from the extension when the binary flag is set to -1. Eventually I plan to have many more file extensions, but not until this is working correctly with a sample of 8.
Getting help in fixing this problem would be most appreciated.
OK, many thanks pmg, that works, except that I have to use:
strcpy_s(ext, EXLEN, fileEx[*code]);
as the Visual Studio 2022 compiler flags an error. This also solves a warning I was getting when I declared the array *fileEx[EXNUM] with the const keyword.
In my haste last night I omitted to include the statement:
if (*code >= EXNUM) return false;
immediately after (3) to trap the case when *code goes out of bounds of *fileEx[EXNUM].
I have to write a function that given two files, compares them both and writes on a third file each word they have in common, I tried with this one, actually making it write on terminal to see if it works, it actually iterates trough the second file but it only compares the first word of the first file, any suggestions?
void fileCopy(FILE *f1,FILE *f2){
char fileString1[100], fileString2[100];
while(!feof(f1)){
fscanf(f1,"%s",fileString1);
while(!feof(f2)){
fscanf(f2,"%s",fileString2);
if(!strcmp(fileString1,fileString2)) printf("%s ",fileString1);
}
}
}
while(!feof(f2)) loops until the end of the second file. You must iterate through both files simultaneously. Instead of these while(!feof... you should be checking the result of each fscanf.
A simple pseudo code example:
while(1)
{
int fscanf1_result = fscanf(f1, ...);
int fscanf2_result = fscanf(f2, ...);
if(fscanf1_result != 1 || fscanf2_result != 1)
{
break;
}
/* rest of the code here */
};
I need help with getting datapoints, x and y values from a txt file into two arrays.
Currently, the text file consists of 5 lines like:
0.116
0.118
0.12
0.122
0.124
This is my code:
#include <stdio.h>
#include <stdlib.h>
main(void)
{
FILE *inp; /* pointer to input file */
double item;
int cnt=0,y,d,i;
double array[300],swap;
/* Prepare files for input */
inp = fopen("testdoc.txt", "r");
/* Read each item */
while ( (fscanf(inp, "%lf", &item) == 1) && (!feof(inp)) ) {
array[cnt] = item;
cnt++;
}
for (int i = 0; i < cnt; i++)
{
printf("%lf\n",array[i]);
}
printf("The total number of inputs is %d",cnt);
fclose(inp); /* Close the files */
return (0);
}
This only reads the first half of the file, which are the x values. Of which output is
0.116000
0.118000
0.120000
0.122000
The total number of inputs is 4
However, I want to read a text file and store the values in two different arrays for x and y values.
The new text file will look like this
0.116,-0.84009
0.118,4.862
0.12,-1.0977
0.122,0.22946
0.124,3.3173
How do i go changing my code above to recognize the Y values after "," sign? And to add both into two arrays at once?
I tried compiling your code posted on pastebin and received an error because of a missing bracket in your while statement.
That's an easy fix.
The larger issue is in the condition of the while loop.
fscanf returns the number of input items converted and assigned on each call.
When you modified your code to return two values, the condition in the while loop fscanf(inp, "%lf,%lf", &v1,&v2) == 1 would fail and the loop will not be entered.
Please modify the while statement to (have included the missing "(" too)..
while ( (fscanf(inp, "%lf, %lf", &v1, &v2) == 2) && (!feof(inp)) )
and you should be good to go!!!
In addition it would be a good practice to include the return type of int for the main function.
I have written a function that is supposed to read the number of sentences in a .txt file, but when the function is called and done, it gives me a value of 0.
This program over all has 3 more functions to figure out different properties of the file and I have them working great. This one is laid out the same way I wrote my other functions just looking for some advice on why I am getting 0 as my number of sentences.
void ptrCntS (FILE* sp1, int sCount)
{
char sentence = 'O';
int myChr;
if (!(sp1 = fopen("Hello.txt", "r")))
{
printf("error opening Hello.txt");
return(1);
}
while ((myChr = fgetc(sp1)) != EOF)
{
if ('.')
{
sentence ='O';
}
else if (sentence == 'O')
{
sCount++;
sentence = 'I';
}
}
fclose(sp1);
printf ("Total number of sentences are:\t%d", sCount);
return;
}
instead of return use return(sCount);
and assign the return value to some int variable in calling function
like
int sentCount;
.
.
.
sentCount=ptrCntS (param1,param2);
if ('.') is always true, thus else... code never reached. Use if( myChr == '.' ) instead.
Function compiles now and runs properly. This function is being called from a switch in a previous function where I had my addresses set and included my print statement for the totals so that I would not have to write another function in the end to call on all my counts and print their results. Instead I set my case 'A': to call all of my counting functions(in this case that is what the original code is) and than display my results. I am sorry for any lengthiness or my hard to understand writing I am new to the C language and I am having a hard time grasping the literature but making some process on understanding the syntax.
I'm having trouble extracting the timings from a .srt (subtitle) file and writing it to another file called output.srt. When i run the following i get some funky stuff written onto the output file.
// where hr=hours,mn=minutes,sc=seconds,ms=mili seconds
#include <stdio.h>
#define LINES 50
#define CHARAC 80
int main(void){
FILE *in;
FILE *out;
char text[LINES][CHARAC];
char timings[LINES][CHARAC];
int i=0,lines=0,items=0;
int hr=0,mn=0,sc=0,ms=0,hr2=0,mn2=0,sc2=0,ms2=0;
in=fopen("file2.srt","r");
out=fopen("output.srt","w");
while (!feof(in)){
fgets(text[i],80,in);
items=sscanf(text[i],"%d:%d:%d,%d --> %d:%d:%d,%d ",&hr,&mn,&sc,&ms,&hr2,&mn2,&sc2,&ms2);
//------------------------------------->edited<----------------------------------
switch (items)
{
case 1: break;
case 8:
sprintf(timings[i],"%d:%d:%d,%d --> %d:%d:%d,%d",hr,mn,sc,ms,hr2,mn2,sc2,ms2);
break;
case 0: break;
}
//------------------------------------->edited<----------------------------------
++i;
}
lines=i;
for (int i=0;i<lines;i++){
fprintf(out,"%s\n",timings[i]);
}
fclose(in);
fclose(out);
return 0;
}
how do I go about extracting those first 10 timings?
If this is on windows (or MSDOS) the open modes need to be text:
in = fopen ("file2.srt", "rt");
out = fopen ("output.srt", "wt");
Secondly, the code isn't doing anything to react to the differently formatted lines. The first few data lines are:
1
00:00:30,909--> 00:00:32,775
Take a look at yourself.
2
00:00:34,066--> 00:00:37,681
Disconnect you from the seats,
lift yourself and take a look in the mirror.
So, naturally, the first sscanf isn't going to fill in most of the fields. Here's the output I got (for the corresponding lines):
1:0:0,0 --> 0:0:0,0
0:0:30,909 --> 0:0:32,775
0:0:30,909 --> 0:0:32,775
0:0:30,909 --> 0:0:32,775
2:0:30,909 --> 0:0:32,775
To fix this, you'll have to add logic which expects the proper number of elements, or at least reacts to them:
itms = sscanf(text[i],"%d:%d:%d,%d --> %d:%d:%d,%d ",&hr,&mn,&sc,&ms,&hr2,&mn2,&sc2,&ms2);
switch (itms)
{
case 1: // the first line
case 8: // the lines with the times
case 0: // the text lines
}
Edited to add a fixed version of your last edit:
#include <stdio.h>
#define LINES 50
#define CHARAC 80
int main(void){
FILE *in;
FILE *out;
char text[LINES][CHARAC];
char timings[LINES][CHARAC];
int i=0,lines=0,items=0;
int hr=0,mn=0,sc=0,ms=0,hr2=0,mn2=0,sc2=0,ms2=0;
in=fopen("file2.srt","rt");
out=fopen("output.srt","wt");
while (!feof(in))
{
if (!fgets(text[i],80,in))
break;
items = sscanf(text[i], "%d:%d:%d,%d --> %d:%d:%d,%d ", &hr,&mn,&sc,&ms,&hr2,&mn2,&sc2,&ms2);
switch (items)
{
case 1: break;
case 8:
sprintf(timings[i],"%d:%d:%d,%d --> %d:%d:%d,%d",hr,mn,sc,ms,hr2,mn2,sc2,ms2);
++i; // advance only when a valid line is seen
break;
case 0: break;
}
}
lines=i;
for (i=0; i<lines; i++){
fprintf(out,"%s\n",timings[i]);
}
fclose(in);
fclose(out);
return 0;
}
The first thing I notice is that you're not checking the result of the sscanf(). You should check the return code to make sure all eight items were scanned in, and only sprintf() to timings[] if the data was scanned correctly.
You need to check the return value from sscanf() to see if the line matched. I downloaded your sample file:
1
00:00:30,909--> 00:00:32,775
Take a look at yourself.
2
00:00:34,066--> 00:00:37,681
Disconnect you from the seats,
lift yourself and take a look in the mirror.
Only some of these lines will return 8 from sscanf() as the number of matches, so test for that. Of course, this will fail if text line matches that, too!
Better would be to look for a blank line (except for the first), then an integer on one line, then the timing. Match only if all three work.