C - Writing on second line of file - c

Im doing the Hangman game on C and I have a trouble on one of the txt files.
I'm trying to append "num_letters" on the second line of the file.My code prints on new line everytime I guess. Is there a "lightweight" way to skip the first line and append on the second one?
void write_stats(int tries, int num_letters)
{
FILE *stats;
stats = fopen("C:\\Users\\rjmal\\Documents\\CLION PROJECTS\\JogoDaForca\\stats.txt", "a");
fprintf(stats," %d",tries);
fprintf(stats,"\n %d",num_letters);
fclose(stats);
}

Here you go:
/* Compiles with: gcc main.c -o test -pedantic -Wall -Wextra */
#include <stdio.h>
int write_stats(const int tries, const int num_letters, FILE* file) {
if (!file)
return -1;
const int written = fprintf(file, "%d\n%d", tries, num_letters);
if (written < 0)
return -1;
return 0;
}
int read_stats(int* tries, int* num_letters, FILE* file) {
if (!file)
return -1;
if (fscanf(file, "%d\n%d", tries, num_letters) != 2)
return -1;
return 0;
}
int main() {
/* writing stats */
FILE* w_stats = fopen("stats.dat", "w");
if (!w_stats) {
fprintf(stderr, "Could not open the file specified!\n");
return 1;
}
if (write_stats(3, 8, w_stats) != 0) {
fprintf(stderr, "Problem occoured while writing stats!\n");
fclose(w_stats);
return 1;
}
fclose(w_stats);
/* reading the stats */
FILE* r_stats = fopen("stats.dat", "r");
if (!r_stats) {
fprintf(stderr, "Could not open the file specified!\n");
return 1;
}
int tries, num_letters;
if (read_stats(&tries, &num_letters, r_stats) != 0) {
fprintf(stderr, "Problem occoured while reading stats!\n");
fclose(r_stats);
return 1;
}
fclose(r_stats);
printf("tries: %d, num_letters: %d\n", tries, num_letters);
return 0;
}
Hopefully it makes sense, I think this does not need any further explanation, since the code explains it itself. However, if you want to clarify something, feel free to ask.

Related

Can't read file in C using fread()

Program asks for input and stores it in a variable, then confirms the operation printing the content of the file. Or at least it had to, when the program ends it doesn't print the file content, I can't seem to find an answer, I've been looking in the docs but can't really figure it out.
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
FILE * file1 = fopen(".out", "w+");
char *s = malloc(513);
fgets(s, 513, stdin);
if (fprintf(file1, "%s", s) < 0)
{
printf("Something failed while writing to the file\n");
return 1;
}
else
{
char *t = malloc(513);
fread(t, sizeof(char), 1, file1);
printf("Success! Input was: %s \n", t);
return 0;
}
}
P.S: Very new to C, though it may seem obvious for you I have no clue whatsoever.
There are 2 issues here,
1 - you wrote to the file handler and you are trying to read from that point onwards - you didnt rewind the file pointer!
2 - you are just reading 1 character and not the amount you wrote to it!
#include <string.h>
...
int n = strlen(s);
rewind(file1); // rewind before read
fread(t, sizeof(char), n, file1); // read as much as you wrote
Some problems in your code:
You are not checking the return value of fopen(), malloc(), fgets() and fread().
You are writing one character to the output stream, without rewinding it.
Here's how your code should look like:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
FILE * file1 = fopen(".out", "w+");
if (!file1) {
printf("Could not open file.\n");
return 1;
}
const size_t n = 513; // Use constants, not litterals.
char *s = malloc(sizeof(char) * n);
if (!s) {
printf("Internal error.\n");
fclose(file1);
return 1;
}
if (!fgets(s, n, stdin)) {
printf("Input failed.\n");
fclose(file1);
return 1;
}
if (fprintf(file1, "%s", s) < 0) {
printf("Something failed while writing to the file\n");
fclose(file1);
return 1;
}
char *t = malloc(sizeof(char) * n);
if (!t) {
printf("Internal error.\n");
fclose(file1);
return 1;
}
rewind(file1);
int ret = fread(t, sizeof(char), n, file1); // Read n characters, not 1.
if (ret != strlen(s)) {
if (feof(file1)) {
printf("Error reading .out: unexpected end of file.\n");
} else if (ferror(file1)) {
perror("Error reading .out");
}
fclose(file1);
return 1;
}
printf("Success! Input was: %s \n", t);
}

how to enter a function to a file in c

I have this function in a code that im trying to enter to an I/O file and I cannot seem to do it.
void show_list(int whyeven[stuff], char *hatred[stuff])
{
for (int g = 0; g < stuff - 1; g++)
{
if (whyeven[g] < 10 || whyeven[g] == 0)
{
printf("%s - %d (*) you should buy more of this stuff\n\n",hatred[g], whyeven[g]);
}
else if (whyeven[g] > 10)
{
printf("%s - %d\n\n", hatred[g], whyeven[g]);
}
}
}
int main()
{
show_list(moarstuff, items);
return 0;
}
printf() prints to stdout. You need to fopen() that file and then use fprintf() with the returned from fopen() FILE* pointer as the first argument.
/* Open the file for writing */
FILE* fp = fopen("filename.txt", "w");
/* Check for errors */
if (fp == NULL)
{
/* Notify the user of the respective error and exit */
fprintf(stderr, "%s\n", strerror(errno));
exit(1);
}
/* Write to the file */
fprintf(fp, "Hello!\n");
/* Close the file */
fclose(fp);
Note: Your question was quite unclear and this answer is based on what I could understand out of it.

Why is my regex function only running the first time around?

I'm working on some code for a homework assignment which is to search a text file for certain patterns and generate reports. Currently to test it I'm just printing my reports to the screen. But my search function only seems to be running the first time. I've tested the regex individually and they do all pull the correct matches but once I put it inside the function it only works the first time it's run. Could anyone explain to me why this is happening?
#include <stdio.h>
#include <stdlib.h>
#include <regex.h>
// Report expressions
char *reports[5] = {"^ {0,}[0-9]{1,4}", "S", "L", "S {0,1}(1|2)", "^ {0,}[0-9]{1,4} {1,} L | 3$"};
void search(FILE *fp, char *report, int index) {
regex_t reg;
char buf[256];
int reti = regcomp(&reg,report,REG_EXTENDED);
if(reti) {
printf("Regex compilation failed, noob\n");
exit(1);
}
printf("Report %d\n", index);
while(fgets(buf,sizeof(buf),fp) != NULL) {
//printf("%s",buf);
reti = regexec(&reg,buf,0,NULL,0);
if(!reti) { //if there's a match
printf("%s",buf);
} else if(reti == REG_NOMATCH) {
printf("No match\n");
}
}
regfree(&reg);
}
int main(void) {
FILE *fp;
fp = fopen("./Hammer.data","r");
if(fp == NULL) {
perror("Error opening file");
return(-1);
}
for(int i = 0;i < 5;i++) {
search(fp, reports[i],i+1);
}
fclose(fp);
return(0);
}
while(fgets(buf,sizeof(buf),fp) != NULL)
That will result in the fp pointing to the end of the file. So the next time the function is called the fgets will immediately return NULL. One fix is to rewind the file pointer before the fgets loop.

Unable to read a file and pass into arguments

1) I'm trying to open a file, read the mix data (ints, chars and strings) and store them into args.
1.1) so in the sample.txt is a total of 13 (excluding args[0])
2) Need to read a file from terminal "./myprog.c < sample.txt"
Heres my code and have no idea where i went wrong:
sample.txt:
123 213 110 90 1
hello my friend
boo bleh
a b c
myprog.c:
#include <stdio.h>
int main()
{
int i = 1;
FILE *fstin=fopen(argv[0], "r"); //open the file
if (fstin == NULL) {
puts("Couldn't fopen...");
return -1;
}
//Getting all the inputs from file
while ((fscanf(fstin, "%d", argv[i])) != EOF){
i++;
}
fclose(fstin);
for (i=0; i<10; i++) {
printf("%d\n",argv[i]);
}
return 0;
}
Any help is greatly appreciated!
PS: Would like if anyone could post their complete solution? Will upload unto this post and let everyone have a review of this problem
PPS: Please excuse the poor level of coding as I am a beginner and completely new to C.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int ac, char *av[]){
int i, argc=0;
char **argv=NULL, data[16];
FILE *fstin = stdin;
if(ac == 2){
if(NULL==(fstin = fopen(av[1], "r"))){
puts("Couldn't fopen...");
return -1;
}
}
while (1==fscanf(fstin, "%15s", data)){
argv = realloc(argv, (argc+1)*sizeof(char*));
argv[argc] = malloc(strlen(data)+1);
strcpy(argv[argc++], data);
}
if(ac == 2)
fclose(fstin);
for (i=0; i<argc; ++i) {
printf("%s\n", argv[i]);
}
//deallocate
return 0;
}
You are making mistake at 2nd point where you divert your file to other file which is wrong. Actually you need to first compile and need to make executable.
gcc -o my_prog ./myprog.c -Wall
You need to execute this program as below to read file from c program:
./my_prog ./sample.txt
As you are new to C programming first go to man pages related to file operations.
Solution:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]) {
//If command line argument is not inserted then stop operation
if (2 != argc) {
printf("Invalid number of arguments : %d\n", argc);
return -1;
}
int size = 0, ret = 0;
char *data = NULL;
FILE *fp = NULL;
//Open file in read mode given from command line argument
if (NULL != (fp = fopen(argv[1], "r")))
{
//Find size of file
fseek(fp, 0L, SEEK_END);
size = ftell(fp);
fseek(fp, 0L, SEEK_SET);
//if file is empty no need to read it.
if (size > 0)
{
//Data pointer which contains file information
data = (char *) calloc(sizeof(char), size);
if (NULL != data)
{
//Read whole file in one statement
fread(data, sizeof(char), size, fp);
printf("File %s is readed successfully\n", argv[1]);
printf("Data:\n");
printf("%s\n", data);
free(data); data = NULL;
}
else
{
perror("memory allocation failed\n");
ret = -1;
}
}
else
{
printf("File %s is empty\n", argv[1]);
}
fclose(fp); fp = NULL;
}
else
{
perror("File open failed\n");
ret = -1;
}
return ret;
}
Now Test it on your setup and if any query please post comments.

How to provide the output of the first input file as the second input file in one pass in C?

Assume that I have a file called 1.lex. An input file 1.c is provided. The output of this is the next input. I want this to happen in a single pass because when the first output is produced, the memory buffer contains some information that is required for the second input file.
Below is the code for file handling for the situation explained above.
char * basename(char *name)
{
char *temp;
int i=0, j=0, len;
temp = (char *)malloc(strlen(name));
len = strlen(name);
len--;
while(1)
{
if(name[len] != '.')
len--;
else
{
for( i = 0; i < len; i++)
temp[j++] = name[i];
break;
}
}
temp[j] = '\0';
return temp;
}
int main(int argc, char** argv)
{
if(argc != 2)
{
fprintf(stderr,"Usage: filename\n");
exit(1);
}
yyin = fopen(argv[1],"r");
if(yyin == NULL)
{
fprintf(stderr,"cannot open file: %s",argv[1]);
exit(0);
}
file = basename(argv[1]);
realloc(file, strlen(file)+10);
strcat(file,".met");
yyout = fopen(file,"w");
yyparse();
return 0;
}
int yywrap()
{
fclose(yyin);
yyin = fopen(file,"r");
if(yyin == NULL)
{
fprintf(stderr,"cannot open file: %s",file);
exit(0);
}
file = basename(file);
realloc(file, strlen(file)+10);
strcat(file,".meta");
yyout = fopen(file,"w");
yyparse();
return 1;
}
If I comment yyparse() in yywrap() function, there is no segmentation fault but nothing gets written in ".meta" file but first o/p file ".met" gets written. If I uncomment, there is segmentation fault and nothing gets written in ".met" file.
Function "basename" is to get the basename of the input.
Function main() which opens the first file and calls yyparse().
When yyparse() is finished with the first file, it calls yywrap(), which opens the next file.
Please see the comment above in the yyparse() line.
If there is another way to solve my problem, please let me know.
Thanks.
Create a pipe and open it for writing and assign it to yyout and open the pipe for reading and assign it to yyin
See http://www.gnu.org/software/libc/manual/html_node/Creating-a-Pipe.html
Similar to the code posted initially. I have explained the changes after the code.
int main(int argc, char** argv)
{
file_num++;
argc = file_num_max;
if(argc != 2)
{
fprintf(stderr,"Usage: filename\n");
exit(1);
}
yyin = fopen(argv[1],"r");
if(yyin == NULL)
{
fprintf(stderr,"cannot open file: %s",argv[1]);
exit(0);
}
file = basename(argv[1]);
realloc(file, strlen(file)+10);
strcat(file,".met");
yyout = fopen(file,"w");
while(yylex())
;
return 0;
}
int yywrap()
{
fclose(yyin);
fclose(yyout);
yyin = fopen(file,"r");
if(++file_num <= file_num_max)
{
if(yyin == NULL)
{
fprintf(stderr,"cannot open file: %s",file);
exit(0);
}
file = basename(file);
realloc(file, strlen(file)+10);
strcat(file,".meta");
yyout = fopen(file,"w");
return 0;
} else {
return 1;
}
}
As said before, function main() which opens the first file and calls yylex().
When yylex() is finished with the first file, it calls yywrap(), which opens the next file, and yylex() continues.
When yywrap() has exhausted all the command line arguments, it returns 1, and yylex().
I just did some small changes and it worked but took some time though!
Cheers.

Resources