#include <stdio.h>
int main(){
char temp[64];
FILE *fp1=fopen("data/1.txt","a");
FILE *fp2=fopen("data/2.txt","r");
while(fgets(temp,64,fp2)!=NULL){
fputs(temp,fp1);
}
fclose(fp1);
fclose(fp2);
return 0;
}
With such code I was able to combine 2 different text file into 1.
data/1.txt contents: abcdefghijk
data/2.txt contents: ABCDE
Outcome: abcdefghijkABCDE
However, I am struggling with shuffling 2 different text file.
Wanted result: aAbBcCdDeEfghijk
Followings are my current code.
#include <stdio.h>
#include <string.h>
int main(){
FILE *fp1,*fp2,*fp_out;
char ch1,ch2;
int result=1;
fp1=fopen("data/1.txt","r");
fp2=fopen("data/2.txt","r");
fp_out=fopen("data/out.txt","w");
//shuffling code area//
fclose(fp1);
fclose(fp2);
fclose(fp_out);
char buf[64]={};
fp_out=fopen("data/out.txt","r");
fgets(buf,64,fp_out);
if(!strncmp("aAbBcCdDeEfghijk",buf,64))
printf("PASS\n");
else
printf("FAIL\n");
fclose(fp_out);
return 0;
}
How can I design a code in "shuffling code area" in order to have outcomes like wanted result? I have thought about making 2 different FOR loops and combining but it kept showed an error.
This is some dirty way to do the job.
You can read the file which ever you want to write first character first and then read a character from second file and write both into third file one after the other.
Just adding extra code as per your need.
This just works for your case , not tested with many cases and corner cases.
#include <stdio.h>
#include <string.h>
int main(){
FILE *fp1,*fp2,*fp_out;
char ch1,ch2;
int result=1;
int file1_content_over = 0;
int file2_content_over = 0;
fp1 = fopen("data/1.txt","r");
fp2 = fopen("data/2.txt","r");
fp_out=fopen("data/out.txt","w");
//shuffling code area//
// read till file1_content_over or file2_content_over is not finished
while(! file1_content_over || !file2_content_over)
{
ch1 = fgetc(fp1);
ch2 = fgetc(fp2);
if(ch1 != EOF)
fputc(ch1,fp_out);
else
file1_content_over = 1;
if(ch2 != EOF)
fputc(ch2,fp_out);
else
file2_content_over = 1;
}
//shuffling code area//
fclose(fp1);
fclose(fp2);
fclose(fp_out);
char buf[64]={};
fp_out=fopen("data/out.txt","r");
fgets(buf,64,fp_out);
printf("buf = %s\n", buf);
if(!strncmp("aAbBcCdDeEfghijk",buf,strlen("aAbBcCdDeEfghijk")))
printf("PASS\n");
else
printf("FAIL\n");
fclose(fp_out);
return 0;
}
Working for me! Not the best optimized code, I didnt get to much time to that!
Main():
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX 100
int removingSPaces(char array[MAX], int sizeArray);
void orderChar(char bufFile1[MAX], char bufFile2[MAX], char bufOut[MAX], int maxSize, int sizeBuf1, int sizeBuf2);
int getChar(char buf[MAX], FILE *fp);
int main(){
FILE *fp1, *fp2, *fpOut;
char bufFile1[MAX] = {0}, bufFile2[MAX] = {0}, bufOut[MAX] = {0};
int sizeBuf1 = 0, sizeBuf2 = 0;
int maxSize=0;
if((fp1=fopen("file1.txt","r")) == NULL || (fp2=fopen("file2.txt","r")) == NULL || (fpOut=fopen("fileOut.txt","w")) == NULL){
perror("");
exit(1);
}
sizeBuf1 = getChar(bufFile1, fp1); //geting the chars from file1
fclose(fp1);
sizeBuf1 = removingSPaces(bufFile1, sizeBuf1); //removing the \n if exists from chars of file1
sizeBuf2 = getChar(bufFile2, fp2); //geting the chars from file2
fclose(fp2);
sizeBuf2 = removingSPaces(bufFile2, sizeBuf2); //removing the \n if exists from chars of file2
maxSize = sizeBuf1 + sizeBuf2; //Max Size to loop for
orderChar(bufFile1, bufFile2, bufOut, maxSize, sizeBuf1, sizeBuf2); //Order the chars!
fprintf(fpOut, "%s", bufOut); //Printing to the file
fclose(fpOut);
/* COPIED FROM YOUR CODE */
char buf[64]={0}; //Just added the 0, because you cant initialize the array like with only {}
if((fpOut=fopen("fileOut.txt", "r")) == NULL){
perror("");
exit(1);
}
fgets(buf,64, fpOut);
if(!strncmp("aAbBcCdDeEfghijk", buf, 64))
printf("PASS\n");
else
printf("FAIL\n");
fclose(fpOut);
/* COPIED FROM YOUR CODE */
return 0;
}
Functions():
int removingSPaces(char array[MAX], int sizeArray){
int size = sizeArray;
if(array[sizeArray -1] == '\n'){
array[sizeArray -1] = '\0';
size = strlen(array);
}
return size;
}
int getChar(char buf[MAX], FILE *fp){
char bufAux[MAX];
int size;
while(fgets(bufAux, sizeof(bufAux), fp)){
size = strlen(bufAux);
}
strcpy(buf, bufAux);
return size;
}
void orderChar(char bufFile1[MAX], char bufFile2[MAX], char bufOut[MAX], int maxSize, int sizeBuf1, int sizeBuf2){
int positionsF1=0, positionsF2=0;
int aux = 0; //This will starts organization by the first file! If you want to change it just change to 1;
for(int i=0; i < maxSize; i++){
if(aux == 0 && positionsF1 != sizeBuf1){
bufOut[i]=bufFile1[positionsF1];
if(positionsF2!=sizeBuf2){
aux = 1;
}
positionsF1++;
}else if(aux == 1 && positionsF2 != sizeBuf2){
bufOut[i]=bufFile2[positionsF2];
if(positionsF1!=sizeBuf1){
aux = 0;
}
positionsF2++;
}
}
}
Content of file 1:
abcdefghijk
Content of file 2:
ABCDE
Related
I am writing a program that takes integer n and n files and combines the file and outputs it on the screen and the file "output.txt". I wrote this code for it but it neither prints it on the screen nor does it write on the file.
#include <stdio.h>
#include <stdlib.h>
size_t file_size(FILE *f){
fseek(f,0,SEEK_END);
size_t size = ftell(f);
fseek(f,0,SEEK_SET);
return size;
}
void copy(FILE *src, FILE *out){
unsigned char buffer[64];
size_t size = file_size(src);
fseek(src,0,SEEK_SET);
while(fread(buffer,sizeof(buffer),1,src) && size > 0){
if (size < 64){
fwrite(buffer, sizeof(buffer),size,out);
printf("%s",buffer);
size = 0;
}
else{
fwrite(buffer,sizeof(buffer),64,out);
size = size - 64;
printf("%s",buffer);
}
}
printf("\n");
}
int main(){
int num;
char file[100];
scanf("%d",&num);
getchar();
FILE *out;
out = fopen("output.txt","w");
if (out == NULL){
exit(1);
}
for (int i=0;i<num;i++){
scanf("%s",file);
getchar();
FILE *src;
src = fopen(file,"rb");
if (src == NULL){
exit(1);
}
copy(src,out);
fwrite("\n",1,1,out);
fclose(src);
}
fclose(out);
}
Can you help me figure out what I am doing wrong here.
What i need to do, is to take a file of n lines, and for every x lines, create a new file with the lines of the original file. An example would be this:
Original File:
stefano
angela
giuseppe
lucrezia
In this case, if x == 2, 3 file would be created, in order:
First file:
stefano
angela
Second FIle:
giuseppe
lucrezia
Third File:
lorenzo
What i've done so far is this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 10
int getlines(FILE *fp)
{
int c = 0;
int ch;
do{
ch = fgetc(fp);
if(ch == '\n')
{
c++;
}
}while(ch != EOF);
fseek(fp, 0 , SEEK_SET);
return c;
}
int ix = 0;
void Split(FILE *fp, FILE **fpo, int step, int lines, int *mem)
{
FILE **fpo2 = NULL;
char * filename = malloc(sizeof(char)*64);
char * ext = ".txt";
char number[2];
for(int i = ix; i < *mem; i++)
{
itoa(i+1, number,10);
strcpy(filename, "temp");
strcat(filename, number);
strcat(filename, ext);
if(!(fpo[i] = fopen(filename, "w")))
{
fprintf(stderr, "Error in writing\n");
exit(EXIT_FAILURE);
}
}
char ch;
int c = 0;
do{
ch = fgetc(fp);
printf("%c", ch);
if(ch == '\n')
{
c++;
}
if(c >= step)
{
c = 0;
ix++;
if(ix >= *mem && (ix*step) <= lines)
{
*mem = *mem + 1;
fpo2 = realloc(fpo, sizeof(FILE*)*(*mem));
Split(fp, fpo2, step, lines, mem);
}
}
putc(ch, fpo[ix]);
}while(ch != EOF);
}
int main()
{
FILE * fp;
if(!(fp = fopen("file.txt", "r")))
{
fprintf(stderr, "Error in opening file\n");
exit(EXIT_FAILURE);
}
int mem = N;
int lines = getlines(fp);
int step = lines/N;
FILE **fpo = malloc(sizeof(FILE *)*N);
Split(fp, fpo, step, lines, &mem);
exit(EXIT_SUCCESS);
}
I'm stack with segmentation error, i couldn't find the bug doing
gdb myprogram
run
bt
I really appreciate any help.
EDIT:
I've changed some things and now it works, but it creates an additional file that contains strange characters. I need to still adjust some things:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 10
int getlines(FILE *fp)
{
int c = 0;
int ch;
do{
ch = fgetc(fp);
if(ch == '\n')
{
c++;
}
}while(ch != EOF);
fseek(fp, 0 , SEEK_SET);
return c;
}
int ix = 0;
void Split(FILE *fp, FILE **fpo, int step, int lines, int *mem)
{
FILE **fpo2 = NULL;
char * ext = ".txt";
for(int i = ix; i < *mem; i++)
{
char * filename = malloc(sizeof(char)*64);
char * number = malloc(sizeof(char)*64);
itoa(i+1, number,10);
strcpy(filename, "temp");
strcat(filename, number);
strcat(filename, ext);
if(!(fpo[i] = fopen(filename, "w")))
{
fprintf(stderr, "Error in writing\n");
exit(EXIT_FAILURE);
}
free(number);
free(filename);
}
char ch;
int c = 0;
do{
ch = fgetc(fp);
printf("%c", ch);
if(ch == '\n')
{
c++;
}
if(c >= step)
{
c = 0;
ix++;
if(ix >= *mem && ((ix-1)*step) <= lines)
{
*mem = *mem + 1;
fpo2 = realloc(fpo, sizeof(FILE*)*(*mem));
Split(fp, fpo2, step, lines, mem);
}
}
putc(ch, fpo[ix]);
}while(ch != EOF);
}
int main()
{
FILE * fp;
if(!(fp = fopen("file.txt", "r")))
{
fprintf(stderr, "Error in opening file\n");
exit(EXIT_FAILURE);
}
int mem = N;
int lines = getlines(fp);
int step = lines/N;
FILE **fpo = malloc(sizeof(FILE *)*N);
Split(fp, fpo, step, lines, &mem);
exit(EXIT_SUCCESS);
}
There are a few problems in your code. But first I think you need to fix the most important thing
int step = lines/N;
Here step is 0 if your input file has less than N lines of text. This is because lines and N both are integer and integer division is rounding down.
I won't fix your code, but I'll help you with it. Some changes I
suggest:
Instead of getlines, use getline(3) from the standard
library.
fseek(fp, 0 , SEEK_SET) is pointless.
In char * filename = malloc(sizeof(char)*64), note that
both arguments to malloc are constant, and the size is arbitrary.
These days, it's safe to allocate filename buffers statically,
either on the stack or with static: char filename[PATH_MAX].
You'll want to use limits.h to get that constant.
Similarly you have no need to dynamically allocate your FILE
pointers.
Instead of
itoa(i+1, number,10);
strcpy(filename, "temp");
strcat(filename, number);
strcat(filename, ext);
use sprintf(filename, "temp%d%s", i+1, ext)
get familiar with err(3) and friends, for your own convenience.
Finally, your recursive Split is -- how shall we say it? -- a nightmare. Your whole program
should be something like:
open input
while getline input
if nlines % N == 0
create output filename with 1 + n/N
open output
write output
nlines++
I tried to change all random lowercase letters to uppercase letters in this program.First of all, I have initialized in lowercase.txt AkfsASlkALfdk.Then I read from it and changing all the lowercase letters into capital ones.The problem is,when I opened the capital.txt is ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌAKFSASLKALFDK.Where did the error come from?I couldn't find it yet and I decided to ask you.
#pragma warning(disable:4996)
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <math.h>
#include <conio.h>
int main()
{
int i;
char s[100];
char k[100];
FILE *kp;
kp = fopen("lowercase.txt", "r");
if (kp == NULL)
{
printf("Error in opening file.\n");
system("pause");
exit(1);
}
FILE *temp;
temp = fopen("capital.txt", "w");
if (kp == NULL)
{
printf("Error in opening file.\n");
system("pause");
exit(2);
}
printf("Opening file is successful.\n");
if (fscanf(kp, "%s", &s) != EOF)
{
for (i = 0; i < 100; i++)
{
if (s[i] >= 97 && s[i] <= 122)
{
s[i] -= 32;
}
}
}
fprintf(temp, "%s", k);
getch();
return 0;
}
Multiple issues in your code which together cause the issues
You are storing the opened FILE* in temp, but checking kp. I think that is because you copy pasted the check from above. Can be easily fixed by changing the variable
You perform the capitalization operation outside what was set by scanf. As suggested by #MOehm, change the loop condition to s[i]
Finally you are converting the string in place in s but are saving k in the file. k is never modified. Change fprintf(temp, "%s", k); to fprintf(temp, "%s", s);
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
char *append(const char *s, char c) {
int len = strlen(s);
char buf[len+2];
strcpy(buf, s);
buf[len] = c;
buf[len + 1] = 0;
return strdup(buf);
}
int main(int argc, char **argv)
{
char ch;
FILE *fp;
if (argc != 2)
return (0);
if ((fp = fopen(argv[1], "r")) == NULL)
{
perror("Error while opening the file.\n");
exit(EXIT_FAILURE);
}
char *res;
while((ch = fgetc(fp)) != EOF)
{
res = append(res, ch);
}
fclose(fp);
int i = 0;
while (i < strlen(res))
{
if (res[i] >= 97 && res[i] <= 122)
res[i] = res[i] - 32;
i++;
}
printf("%s\n", res);
return 0;
}
here is a quick example
read the file char by char and add each char in a char *. Then for each character lowercase char, sub 32 to get the uppercase char and write it then print. Give the filename as first parameter when you start the programm
This is the code why when I show in output the string I have all words but with in the final row a strange symbol , an ASCII random symbol...
My objective is to save in a string all words to operate with it.
For example I have this document:
Mario
Paul
Tyler
How can i save all words in a string??
#include <stdio.h>
#include <stdlib.h>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
int main(int argc, char *argv[]) {
int l,i=0,j=0,parole=0;
char A[10][10];
char leggiparola;
char testo[500];
FILE*fp;
fp=fopen("parole.txt","r");
if(fp!=NULL)
{
while(!feof(fp))
{
fscanf(fp,"%c",&leggiparola);
printf("%c", leggiparola);
testo[j]=leggiparola;
j++;
}
}
fclose(fp);
printf("%s",testo);
return 0;
}
Besides while(!feof(fp)) being "always wrong" you miss to 0-terminate the result string.
To do so place a
testo[j] = '\0'
just after the while-loop.
Instead of using fscanf, try with getc:
int leggiparola; /* This need to be an int to also be able to hold another
unique value for EOF besides 256 different char values. */
...
while ( (leggiparola = getc(fp)) != EOF)
{
printf("%c",leggiparola);
testo[j++] = leggiparola;
if (j==sizeof(testo)-1)
break;
}
testo[j] = 0;
Here's fslurp. I't a bit messy due to the need to grow the buffer manually.
/*
load a text file into memory
*/
char *fslurp(FILE *fp)
{
char *answer;
char *temp;
int buffsize = 1024;
int i = 0;
int ch;
answer = malloc(1024);
if(!answer)
return 0;
while( (ch = fgetc(fp)) != EOF )
{
if(i == buffsize-2)
{
if(buffsize > INT_MAX - 100 - buffsize/10)
{
free(answer);
return 0;
}
buffsize = buffsize + 100 * buffsize/10;
temp = realloc(answer, buffsize);
if(temp == 0)
{
free(answer);
return 0;
}
answer = temp;
}
answer[i++] = (char) ch;
}
answer[i++] = 0;
temp = realloc(answer, i);
if(temp)
return temp;
else
return answer;
}
I must modify my program to accept input from
a file called anagrams.txt.This file should have two strings per line, separated by the # character. My program should read
each pair of strings and report back if each pair of strings is an anagram. For example consider the following content of anagrams.txt:
hello#elloh
man#nam
Astro#Oastrrasd
Your program should print out the following:
hello#elloh - Anagrams!
man#nam - Anagrams!
Astro#Oastrrasd- Not anagrams!
I should compile in g++
Here is the code to read from text:
int main()
{
char input[30];
if(access( "anagrams.txt", F_OK ) != -1) {
FILE *ptr_file;
char buf[1000];
ptr_file =fopen("anagrams.txt","r"); if (!ptr_file)
return 1;
while (fgets(buf,1000, ptr_file)!=NULL)
printf("%s",buf);
fclose(ptr_file);
printf("\n");
}
else{ //if file does not exist
printf("\nFile not found!\n");
}
return 0;
}
Code to find if the text are anagrams:
#include <stdio.h>
int find_anagram(char [], char []);
int main()
{
char array1[100], array2[100];
int flag;
printf("Enter the string\n");
gets(array1);
printf("Enter another string\n");
gets(array2);
flag = find_anagram(array1, array2);
if (flag == 1)
printf(" %s and %s are anagrams.\n", array1, array2);
else
printf("%s and %s are not anagrams.\n", array1, array2);
return 0;
}
int find_anagram(char array1[], char array2[])
{
int num1[26] = {0}, num2[26] = {0}, i = 0;
while (array1[i] != '\0')
{
num1[array1[i] - 'a']++;
i++;
}
i = 0;
while (array2[i] != '\0')
{
num2[array2[i] -'a']++;
i++;
}
for (i = 0; i < 26; i++)
{
if (num1[i] != num2[i])
return 0;
}
return 1;
}
You can try something like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define MAXLINE 1000
#define MAXLETTER 256
int is_anagram(char *word1, char *word2);
void check_lines(FILE *filename);
int cmpfunc(const void *a, const void *b);
void convert_to_lowercase(char *word);
int
main(int argc, char const *argv[]) {
FILE *filename;
if ((filename = fopen("anagram.txt", "r")) == NULL) {
fprintf(stderr, "Error opening file\n");
exit(EXIT_FAILURE);
}
check_lines(filename);
fclose(filename);
return 0;
}
void
check_lines(FILE *filename) {
char line[MAXLINE];
char *word1, *word2, *copy1, *copy2;
while (fgets(line, MAXLINE, filename) != NULL) {
word1 = strtok(line, "#");
word2 = strtok(NULL, "\n");
copy1 = strdup(word1);
copy2 = strdup(word2);
convert_to_lowercase(copy1);
convert_to_lowercase(copy2);
if (is_anagram(copy1, copy2)) {
printf("%s#%s - Anagrams!\n", word1, word2);
} else {
printf("%s#%s - Not Anagrams!\n", word1, word2);
}
}
}
void
convert_to_lowercase(char *word) {
int i;
for (i = 0; word[i] != '\0'; i++) {
word[i] = tolower(word[i]);
}
}
int
is_anagram(char *word1, char *word2) {
qsort(word1, strlen(word1), sizeof(*word1), cmpfunc);
qsort(word2, strlen(word2), sizeof(*word2), cmpfunc);
if (strcmp(word1, word2) == 0) {
return 1;
}
return 0;
}
int
cmpfunc(const void *a, const void *b) {
if ((*(char*)a) < (*(char*)b)) {
return -1;
}
if ((*(char*)a) > (*(char*)b)) {
return +1;
}
return 0;
}
Since this looks like a University question, I won't provide a full solution, only a hint.
All you have to do is replace the stdin input part of the anagram-finding file with the code you wrote to read from a file: it's as simple as changing
printf("Enter the string\n");
gets(array1);
printf("Enter another string\n");
gets(array2);
to
// before program:
#define SIZE 1000
// inside main
if (access("anagrams.txt", F_OK) == -1){
printf("\nFile not found!\n");
return 1; // Abort the program early if we can't find the file
}
FILE *ptr_file;
char buf[1000];
ptr_file = fopen("anagrams.txt","r");
if (!ptr_file)
return 1;
char array1[SIZE], array2[SIZE];
while (fgets(buf, 1000, ptr_file)!=NULL){
// do all your anagram stuff here!
// there is currently one line of the input file stored in buf
// Hint: You need to split buf into array_1 and array_2 using '#' to separate it.
}
fclose(ptr_file);
printf("\n");
Additional comments:
Don't ever ever ever use gets. gets doesn't check that the string it writes to can hold the data, which will cause your program to crash if it gets input bigger than the array size. Use fgets(buf, BUF_SIZE, stdin) instead.
Beautiful code is good code. People are more likely to help if they can read your code easily. (fix your brackets)
Just for interest, a more efficient algorithm for checking anagrams is to use qsort to sort both arrays, then a simple string matcher to compare them. This will have cost O(mnlog(m+n)), as opposed to O(m^2 n^2), awith the current algorithm
You need to split every line you read by fgets (as you did) in to two strings, and pass them to your find_anagram function. You can do that using strtok:
int main()
{
int flag;
char buf[1000];
FILE *ptr_file;
//Check file existence
//Open the file for reading
while (fgets (buf, 1000, ptr_file) != NULL)
{
char *array1 = strtok(buf, "#");
char *array2 = strtok(NULL, "\n");
flag = find_anagram (array1, array2);
//Check flag value to print your message
}
return 0;
}
//put your find_anagram function
Don't forget to #include <string.h> to use strtok().