I am creating a program which copies text file data from one file and changes its case to lower or upper on choice, but when I execute the program I receive the following result and the text case is not changed or copied.
#include <stdio.h>
int main() {
FILE *fp = NULL;
FILE *fp2 = NULL;
char str[200];
char var;
int i;
char copy;
fp = fopen("file1.txt", "a");
fp2 = fopen("file2.txt", "w");
printf("Enter choice: ");
scanf(" %c", &var);
if (fp != NULL && var == 'L') {
while ( fgets(str, 200, fp) != NULL ) {
putchar(tolower(fp[i]));
i++;
}
puts(str);
}
else if (fp != NULL && var == 'U') {
while ( fgets(str, 200, fp) != NULL ) {
putchar(toupper(fp[i]));
i++;
}
puts(str);
}
else {
printf("ERROR: No proper choice was made \n");
}
while (1) {
copy = fgetc(fp);
if (copy == EOF) {
break;
}
else {
putc(copy , fp2);
}
}
return 0;
fclose(fp);
fclose(fp2);
}
The output I get is:
Enter choice: U
▒▒
putchar(tolower(fp[i])); should have generated compiler warnings. Insure the compiler warning are all enabled or consider a new compiler.
Replace in 2 places, both upper and lower section.
while ( fgets(str, 200, fp) != NULL ) {
putchar(tolower(fp[i]));
i++;
}
// With to iterate over each character
while (fgets(str, sizeof str, fp) != NULL) {
for (i=0; str[i]; i++) {
putchar(tolower(str[i]));
}
}
Change to int to properly distinguish all characters returned from fgetc() from EOF.
Open with "r" to read from the beginning of the file
// fp = fopen("file1.txt", "a")
fp = fopen("file1.txt", "r");
The problem is that you use fgets, which reads a string from the file. A better way of doing this would be to use fgetc, which reads just one character at a time and process it appropiately.
Related
I've been trying to merge the contents of two .txt files into a third .txt file that combines the output. All I know how to do (and all I have been able to find answers for), however, is to merge them by putting the contents of the first file first, and the second file second. However, I would prefer the output to list the first line of the first file, then the first line of the second file -- followed on a new line by the second line of the first file and the second line of the second file.
To make this clearer visually, the code is currently appearing as:
file1-line1
file1-line2
file1-line3
file2-line1
file2-line2
file2-line3
... When I'd like it to appear as:
file1-line1 file2-line1
file1-line2 file2-line2
file1-line3 file2-line3
The code I have is very basic and executes the first example fine:
int main()
{
FILE *pointer1 = fopen("file1.txt", "r");
FILE *pointer2 = fopen("file2.txt", "r");
FILE *pointer3 = fopen("combined.txt", "w");
int ch;
if (pointer1 == NULL || pointer2 == NULL || pointer3 == NULL)
{
puts("Could not open files");
exit(0);
}
while ((ch = fgetc(pointer1)) != EOF)
fputc(ch, pointer3);
while ((ch = fgetc(pointer2)) != EOF)
fputc(ch, pointer3);
printf("Merged file1.txt and file2.txt into combined.txt");
fclose(pointer1);
fclose(pointer2);
fclose(pointer3);
return 0;
}
Is there a way to output the described situation? I am aware that E0F refers to the end of a file, and is likely causing an issue. Is there a similar condition for an end of a line (like E0L)?
Edit: Changed char ch to int ch.
First, if you have a Unix-like system, the paste command already does that. Next as you want to process lines, you should use fgets. Here you have to loop over input files one line at a time, copy the lines to the output file without the newline, and add the new line after copying everything.
As the processing for both input files is the same, and as I am lazy, I wrote a function to only write it once. In the end code could be:
FILE *copyline(FILE *in, FILE *out) {
char line[256];
if (in != NULL) {
for (;;) { // loop if the line is larger that sizeof(line)
if (NULL == fgets(line, sizeof(line), in)) { // EOF on file1
fclose(in);
in = NULL;
break;
}
size_t end = strcspn(line, "\n");
if (end != 0) fwrite(line, 1, end, out); // smth to write
if (end != strlen(line)) break; // \n found: exit loop
}
}
return in;
}
int main()
{
FILE *pointer1 = fopen("file1.txt", "r");
FILE *pointer2 = fopen("file2.txt", "r");
FILE *pointer3 = fopen("combined.txt", "w");
const char sep[] = " "; // a separator between lines of both file
if (pointer1 == NULL || pointer2 == NULL || pointer3 == NULL)
{
puts("Could not open files");
exit(0);
}
for (;;) {
pointer1 = copyline(pointer1, pointer3);
fwrite(sep, strlen(sep), 1, pointer3);
pointer2 = copyline(pointer2, pointer3);
if (pointer1 == NULL && pointer2 == NULL) break;
fputc('\n', pointer3); // if smth was written, add a newline
printf(".");
}
printf("Merged file1.txt and file2.txt into combined.txt");
fclose(pointer3);
return 0;
}
Here's one way to approach it:
#include <err.h>
#include <libgen.h>
#include <stdio.h>
#include <stdlib.h>
FILE *
xfopen(const char *path, const char *mode)
{
FILE *fp = path[0] != '-' || path[1] != '\0' ? fopen(path, mode) :
*mode == 'r' ? stdin : stdout;
if( fp == NULL ) {
perror(path);
exit(EXIT_FAILURE);
}
return fp;
}
int
main(int argc, char **argv)
{
if( argc < 3 ) {
printf("usage: %s file1 file2\n", basename(argv[0]));
}
FILE *pointer1 = xfopen(argv[1], "r");
FILE *pointer2 = xfopen(argv[2], "r");
FILE *current = pointer1;
int ch;
while( ( ch = fgetc(current)) != EOF ) {
if( ch == '\n' ) {
if( current == pointer1 ) {
int k;
current = pointer2;
if( (k = fgetc(current)) != EOF ) {
ungetc(k, current);
ch = ' ';
}
} else {
current = pointer1;
}
}
putchar(ch);
}
if( ferror(current) ) {
err(EXIT_FAILURE, "Error reading %s",
current == pointer1 ? argv[1] : argv[2]);
}
current = current == pointer1 ? pointer2 : pointer1;
while( (ch = fgetc(current)) != EOF) {
putchar(ch);
}
fclose(pointer1);
fclose(pointer2);
return 0;
}
#include <stdio.h>
int main()
{
FILE *pointer1 = fopen("file1.txt", "r");
FILE *pointer2 = fopen("file2.txt", "r");
FILE *pointer3 = fopen("combined.txt", "w");
char ch1, ch2;
if (pointer1 == NULL || pointer2 == NULL || pointer3 == NULL)
{
puts("Could not open files");
return 0;
}
do
{
char c1 = fgetc(pointer1);
char c2 = fgetc(pointer2);
if (feof(pointer1) || feof(pointer2))
break;
while(c1!='\n')
{
fputc(c1,pointer3);
c1=fgetc(pointer1);
if(feof(pointer1)) break;
}
fputc(' ',pointer3);
while(c2!='\n')
{
fputc(c2,pointer3);
c2=fgetc(pointer2);
if(feof(pointer2)) break;
}
fputc('\n',pointer3);
} while (1);
printf("Merged file1.txt and file2.txt into combined.txt");
fclose(pointer1);
fclose(pointer2);
fclose(pointer3);
return 0;
}
This works like you want.
Output: Combined file.txt
file1-line1 file2-line1
file1-line2 file2-line2
file1-line3 file2-line3
As title states, I'm trying to read numbers from an external text file and assign them to an array. I'm able to manipulate the array and write the result to another file if I manually create the array, but as is, the fscanf() is pulling garbage from the text file. This is what I currently have, I've been reading other posts here and I've changed it like 12 times now but I think I'm getting farther from the solution.
filename = argv[1];
FILE *fp;
fp = fopen(filename, "r");
if (fp == NULL) {
printf("\n Unable to open input file.\n\n");
helpmssg();
exitmssg();
}
while (getc(fp) != EOF){
if (fscanf(fp,"%d", &c) == 1) {
arr[i] = c;
i++;
}
}
Ideally this should scan the file specified as a command line argument for a number, assign it to the first spot of the array, and repeat until the end of file. Any help is greatly appreciated.
Text file:
12
23
99
66
47
2
-111
8
Per request adding whole main function:
void main(int argc,char** argv) {
char* filename;
char* outputfile;
char conf;
int arr[1000] = {0};
int n,a=0,d=0,h=0,i=0,c=0;
welcome();
if (argc > 4 || argc < 3) {
printf("\n Invalid number of arguments.\n\n");
helpmssg();
exitmssg();
}
else if (argc == 4) {
for (int i=3;i<argc;i++) {
if (argv[i][0] == '-') {
for(int z=1;z<strlen(argv[i]);z++) {
if (argv[i][z] == 'a') {
a=1;
}
else if (argv[i][z] == 'd') {
d=1;
}
else if (argv[i][z] == 'h') {
h=1;
}
else {
printf("\n Invalid options in 3rd argument.\n\n");
helpmssg();
exitmssg();
}
}
}
else {
printf("\n 3rd argument shoule begin with '-'\n\n");
helpmssg();
exitmssg();
}
} }
filename = argv[1];
FILE *fp;
fp = fopen(filename, "r");
if (fp == NULL) {
printf("\n Unable to open input file.\n\n");
helpmssg();
exitmssg();
}
while ((c=getc(fp)) != EOF){
ungetc (c,fp);
if (fscanf(fp,"%d\n", &c) == 1) {
arr[i] = c;
i++;n++;
}
}
// int arr[] = {64, 34, 25, 12, 22, 11, 90};
sort(arr, n,d);
printf("Sorted array: \n");
printArray(arr, n);
outputfile = argv[2];
fp = fopen(outputfile, "r");
if (fp != NULL ) {
printf("\n Output file already exists, would you like to overwrite it?: Y/N \n\n");
scanf("%c", &conf);
if (conf == 'N' || conf == 'n') {
helpmssg();
exitmssg();
} else {printf(" Overwritting...\n\n");}
}
fclose(fp);
fp = fopen(outputfile, "w");
for (i=0; i < n; i++) {
fprintf(fp,"%d\n",arr[i]);
}
exitmssg();
}
You could do
for(i=0; i<size ; ++i)
{
if( fscanf(fp, "%d", &arr[i])!=1 )
{
printf("\nSomething went wrong.");
break;
}
}
where size is the number of numbers stored in the array.
Use fscanf() to read the integers in each line one by one. It returns the number of successful assignments which in this case should be 1 in each iteration of the loop.
In your program, you first use getc(), which reads one character, and then use fscanf() which reads only the rest.
Change while (getc(fp) != EOF) to while ((c = getc(fp)) != EOF).
Add ungetc (c, fp); below it in the loop and before the if statement.
Change if (fscanf(fp,"%d", &c) == 1) { to if (fscanf(fp,"%d\n", &c) == 1) {
I have a practice question in C that asks me to create a function that only copies part of a file to another one. The restrictions are that lines with greater than maxlen characters are not copied to the new file, and the newline character does not count, so it should not be copied. Part of my function says that if a file does not exist, it should explicitly say so, and I am getting those error messages when I run that code; however, I can see that the files are created are inside my folder. Whenever I open the file I'm trying to read after running the code, I get this:
./Debug/main.c.o ./Debug/dot.c.o ./Debug/dataBase.c.o ./Debug/intPrompt.c.o ./Debug/numWords.c.o ./Debug/LinkedList.c.o
Below is my code :
void shortLines(char* f1, char* f2, int maxlen) {
FILE* fp = fopen(f1, "r");
FILE* fp2 = fopen(f2, "w");
if (fp == NULL) {
perror("File does not exist");
}
if (fp2 == NULL) {
perror("File does not exist");
}
char singleLine[maxlen];
char check;
size_t len;
do {
fgets(singleLine, maxlen, fp);
len = strlen(singleLine);
if (singleLine[len-1] == '\n') {
singleLine[len-1] = '\0';
}
fprintf(fp2, "%s", singleLine);
} while ((check=getc(fp) != EOF));
}
int main(int argc, char **argv) {
shortLines("Andrew.txt", "Andrew2.txt", 25);
return 0;
}
I just made new files called Andrew.txt and Andrew2.txt and these ones seem to be working for some strange reason. Regardless, there were a few problems in the code. First of all, after fgets is called, I needed to make sure to flush out the remaining characters in the line. I do this with a while loop and fgetc. If I reach an EOF, then I continue, and then fgets also returns an EOF, thus breaking the outer loop.
void shortLines(char* f1, char* f2, int maxlen) {
FILE* fp = fopen(f1, "r");
FILE* fp2 = fopen(f2, "w");
if (fp == NULL) {
perror(f1);
}
if (fp2 == NULL) {
perror(f2);
}
char line[maxlen+1];
size_t len;
char c;
while (fgets(line, maxlen+1, fp) != NULL) {
len = strlen(line);
if (len == maxlen) {
while ((c=fgetc(fp)) != '\n') {
if (feof(fp)) {
break;
}
}
continue;
}
if (line[len-1] == '\n') {
line[len-1] = '\0';
}
fprintf(fp2, "%s\n", line);
}
}
The log.txt file consist of some data. The program looks for ":" and when it find it prints "Done". The program compiles successfully but never prints "Done".
char *atrbt ;
FILE *fp;
int i = 0;
if (fp = fopen("log.txt", "r+")) {
while (fscanf(fp, "%c", &atrbt) != EOF) {
printf("%c", atrbt);
if(atrbt[i] == ':') { <------------ Issue
printf("Done");
}
++i;
}
}
You are mixing between char and char pointers. One of the possible correct ways could be (code is untested):
char atrbt;
FILE *fp;
if (fp = fopen("log.txt", "r+")) {
while ((atrbt = getc(fp)) != EOF) {
printf("%c", atrbt);
if(atrbt == ':') {
printf("Done");
}
}
}
I want to write code were the user is asked to write the name of a file. Then I want to analyze the file's content for a symbol, let's say 'e'.
My problem is that I don't know how to start analyzing the file the correct way so that the content can be checked.
int main() {
char c[1000], file_name[1000];
int i;
int s = 0;
FILE *fp;
printf("Enter the name of file you wish to see\n");
gets(file_name);
if ((fp = fopen(file_name, "r")) == NULL){
printf("Error! opening file");
exit(1);
}
if (fp) {
while (fscanf(fp, "%s", c) != EOF) {
printf("%s", c);
}
fclose(fp);
for (i = 0; c[i] != '\0'; ++i) {
puts(c);
if (c[i] == 'e') {
++s;
}
}
printf("\nWhite spaces: %d", s);
_getche();
return 0;
}
}
char line[512]; /*To fetch a line from file maximum of 512 char*/
rewind(fp);
memset(line,0,sizeof(line)); /*Initialize to NULL*/
while ( fgets(line, 512, fp ) && fp !=EOF)
{
/*Suppose u want to analyze string "WELL_DONE" in this fetched line.*/
if(strstr(line,"WELL_DONE")!=NULL)
{
printf("\nFOUND KEYWOD!!\n");
}
memset(line,0,sizeof(line)); /*Initialize to null to fetch again*/
}
If its just a symbol you're looking for, or a char, you can simply use getc() :
int c;
....
if (fp) {
while ((c = getc(fp)) != EOF) {
if (c == 'e') {
// Do what you need
}
}
Or, alternatively, if it's a word you're looking for, fscanf() will do the job:
int c;
char symb[100];
char symbToFind[] = "watever"; // This is the word you're looking for
....
while ((c = fscanf(fp, %s, symb)) != EOF) {
if (strcmp(symb, symbToFind) == 0) { // strcmp will compare every word in the file
// do whatever // to symbToFind
}
}
These alternatives will allow you to search every char or string in the file, without having to save them as an array.