Unable to use fseek() in backward direction from the current position - c

I am searching a string inside the the content of a file and storing the whole content in a buff char[] by excluding the space ' ' and at last comparing the this buff char[] with user input string for checking the availability.
But I am unable to store the whole file content because fgetc() is checking the space in if condition and placing to the next char even though I tried to use fseek() for pointing to the 1 char backward from the current position; it is making my program to terminate.
Please help me; my code follows:
#include <stdio.h>
#include <stdlib.h>
FILE *file;
int file_size;
int main(void) {
file= fopen("C:/Users/home/Desktop/dummy/s.txt","r");
file_exist(file);
fclose(file);
return 0;
}
void file_exist(file)
{
if(file)
{
printf("file exists\n");
content_exist(file);
}
else
{
printf("it doesnt exist\n");
}
}
void content_exist(file)
{
fseek(file,0,SEEK_END);
file_size=ftell(file);
rewind(file);
char user_input[10];
if(file_size==0)
{
printf("content does not exists\n");
}
else
{
printf("content exist\n");
printf("enter the word needs to be matched\n");
scanf("%s",&user_input);
check_string(user_input);
}
}
void check_string(user_input)
{
char buff[file_size];
int temp=0;
while(!feof(file))
{
printf("hi\n");
if(fgetc(file)!=' ')
{
fseek(file, -1,SEEK_CUR);
buff[temp]= fgetc(file);
temp++;
}
}
if(strcmp(user_input,buff)==0)
{
printf("your content matched\n");
}
else
{
printf("your content not matched\n");
}
}

For your purpose, there doesn't seem to be any reason to use fseek.
Change this:
if (fgetc(file) != ' ')
{
fseek(file,-1,SEEK_CUR);
buff[temp] = fgetc(file);
temp++;
}
To this:
buff[temp] = fgetc(file);
if (buff[temp] != ' ')
temp++;
And of course, in order to use strcmp safely, you must terminate buff with a null-character:
buff[temp] = 0;
if (strcmp(user_input,buff) == 0)
...
Hence, please note that for a file with no space characters you will need char buff[file_size+1].

Fseek with integer values like -1 only work on binary files. Source
Try fopen with "rb" instead of just "r"

Related

Read words from file and put them in array

I want to read the words from a text file into an array.
Why does this code work with a 2D array (a[50][50]) but not with a 1D array (a[50])?
This code prints what I want but it also print some other useless characters. What causes this?
void inputwords(){
int i=0;
char wrd[50];
FILE * fptr;
char fname[20]="txt.file";
fptr=fopen(fname,"w");
if(fptr==NULL) {
printf("error in opening file!");
exit(1);
}
while(wrd!='\0'){
fgets(wrd,sizeof wrd,stdin);
fprintf(fptr,"%s",wrd);
if(wrd[i]=='*' && wrd[i+1]=='*' && wrd[i+2]=='*' && wrd[i+3]=='*' &&
wrd[i+4]=='T' && wrd[i+5]=='E' && wrd[i+6]=='L' && wrd[i+7]=='O' &&
wrd[i+8]=='S') {
break;
}
}
fclose(fptr);
return;
}
void readfile(){
FILE *fptr;
char a[50][50];
int i=0;
char fname[20]="txt.file";
fptr=fopen(fname,"r");
while(fgets(a[i],50,fptr)){
i++;
}
for(i=0;i<50;i++){
printf("%s",a[i]);
}
fclose(fptr);
return;
};
main(){
inputwords();
readfile();
return(0);
}
for(i=0;i<50;i++){
printf("%s",a[i]);
}
This prints out the value of every pointer in a[50]. Once you reach past the char pointers which are actually set to point to something, you're just printing out the value of the pointer itself.
for(int n=0; n<i; n++){
printf("%s",a[n]);
}
Would work.
I just tested the answer of Cowbolt, it works , and also wanted to ask you why do you have the line in inputwords() :
while(wrd!='\0') {
The condition of null character will never happen from user input. It is better to have clear instructions and say :
printf("Enter text (to finish input, type on a line of its own:****TELOS ):");
while (1) {
/*be aware that your final i marks the position of string "****TELOS" */
/* so if you dont want it to output, have the n<i-1 in Cowbolt solution*/

Replacing specific text of a file in C

Alright, so basically what I have to do is change all the numbers of a text file to dollar sign, I know how to scan for the specific character but I am stuck on how to replace that specific character with dollar sign. I don't want to use fseek or any library commands, how do I proceed and why isn't my code working?
#include<stdio.h>
main()
{
FILE* fptr;
char filename[50];
char string[100];
int i;
printf("Enter the name of the file to be opened: ");
scanf("%s",filename);
fptr=fopen(filename,"w");
if(fptr==NULL)
{
printf("Error occurred, try again.");
return 0;
}
fgets(string,"%s",fptr);
do
{
if(string[i]>='1' && string[i]<='9')
{
string[i]='$';
}
}
while(i!=100);
fclose(fptr);
}
There are basically two approaches at first glance, the first is to use fseek() and the second to read the file in its entirety and replace the characters to your criteria and finally write that in one shot. You can choose either of the approaches depending on your need. For large file you should prefer the former and for small file you can prefer the latter.
Here's an example code of the former:
#include <stdio.h>
int main() {
// Open the file
FILE *fptr = fopen("input.txt", "r+");
if (!fptr) {
printf("Error occurred, try again.");
return -1;
}
int c;
// Iterate through all characters in a file
while ((c = getc(fptr)) != EOF) {
// Check if this current character is a digit?
if (c >= '0' && c <= '9') {
// Go one character back
if (fseek(fptr, -1, SEEK_CUR) != 0) {
fprintf(stderr, "Error while going one char back\n");
return -1;
}
// Replace the character with a '$'
if (fputc('$', fptr) == EOF) {
fprintf(stderr, "Error while trying to replace\n");
return -1;
}
}
}
// Flush the changes to the disk
if (fflush(fptr) != 0) {
fprintf(stderr, "Error while flushing to disk\n");
return -1;
}
// Close the file
fclose(fptr);
return 0;
}

fscanf in a loop saving to the same array causes spaces to fill array

I have a file formatted like:
01,Name1
02,Name2
03,Name3
04,Name4
05,Name5
I am tying it make it so that a user can type in a number like 01, or 02 and the corresponding name will be returned. This works fine when I type 01. However when I type any number after it doesn't work and it seems like when I replace the loop with:
fscanf(fp,"%20[^,],%s[^\n]",ln,name);
printf("1=%c 2=%c 3=%c 4=%c\n",ln[0],ln[1],search[0],search[1]);
fscanf(fp,"%20[^,],%s[^\n]",ln,name);
printf("1=%c 2=%c 3=%c 4=%c\n",ln[0],ln[1],search[0],search[1]);
The 2nd time around the ln[0] gets filled with a lot of spaces or a "\n". I can't tell.
Any help will be appreciated.
Here is my code:
#include <stdio.h>
int main()
{
puts("Enter seach number:");
char search[2];
scanf("%c%c",&search[0],&search[1]);
FILE *fp;
fp = fopen("/Users/user1/Desktop/text.txt","r");
if(fp == NULL){
puts("File dose not exits");
return (1);
}
else{
puts("File found");
}
char ln[3];
char name[20];
fopen("fp","r");
puts("File opened");
int searching = 1;
while(searching == 1)
{
fscanf(fp,"%20[^,],%s[^\n]",ln,name);
if(ln[0]==search[0]&&ln[1]==search[1])
{
printf("%s",name);
searching = 0;
}
else if(ln[0] == '\n')
{
puts("Could not find number");
searching = 0;
}
}
return 0;
}
Wrong use of fscanf() format
// fscanf(fp,"%20[^,],%s[^\n]",ln,name);
fscanf(fp,"%20[^,],%s%*[^\n]",ln,name);
// or
fscanf(fp,"%20[^,],%s ",ln,name);
// or
fscanf(fp," %20[^,],%s",ln,name);
Better to check results and add width to %s
char ln[20+1];
char name[30+1];
if (2 == fscanf(fp,"%20[^,],%30s%*[^\n]",ln,name)) Success();
Best to use fgets()
char buf[100];
if (fgets(buf, sizeof buf, fp) == NULL) {
if (2 == sscanf(buf,"%20[^,],%s",ln,name)) Success();
}

Extra character at end while copying?

This is making me nuts I am trying to make a simple program to copy any type of file using the following code but the result I get is unexpected (one or two extra characters at the end of copied file?). For instance if my original file has This is an example the copied file contains This is an exampleÿ
CODE
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *fp,*fpp;
char pbuff, fname[32];
int i;
printf(" FILE NAME TO OPEN : ");
scanf(" %32s", fname);
fp = fopen(fname, "rb");
fpp = fopen("file", "wb");
if(fp==NULL)
{
printf("NO SUCH FILE. EXITING NOW.");
getch();
exit(1);
}
while(!feof(fp))
{
pbuff = fgetc(fp);
fputc(pbuff, fpp);
}
printf("SUCCESSFULLY CREATED!");
fclose(fp);
fclose(fpp);
getch();
return(0);
}
Can anyone help me out with this one? I will be really very thankful.
The reason is that feof (like most end-of-file indicators in most languages/environments) is only set AFTER the end-of-file has been reached. Since you write the character and only then check the EOF status, you're writing 1 too many characters. fgetc's return value is a predefined EOF if the end-of-file was reached during the call.
You could solve that in 1 of 2 ways:
while(true)
{
pbuff = fgetc(fp);
if(feof(fp))
break;
fputc(pbuff, fpp);
}
Or: (edit as melpomene correctly noticed!)
// Change pbuff to type int in the declartion, and then...
while(true)
{
pbuff = fgetc(fp);
if(EOF == pbuff)
break;
fputc(pbuff, fpp);
}

Word palindrome in C

My task is to find word palindromes in a text file and to NOT print them into results file. The results file should only contain all the spaces and words that are NOT palindromes. I've been working on this program for two solid weeks, but as I am a total newb in C, I can't simply imagine how to do this correctly. Also, I have to work in Linux environent, so I can't use commands like strrev() which would make my life a lot easier at this point...
Anyways, data file contains a lot of words in a lot of lines separated by quite a few spaces.
Here is the program that is working, but doesn't work with any spaces, because I don't know how to check them at the needed place.
#include <stdio.h>
#include <string.h>
const int CMAX = 1000;
const int Dydis = 256;
FILE *dataFile;
FILE *resFile;
void palindrome(char *linex);
int main(){
char duom[CMAX], res[CMAX], linex[Dydis];
printf("What's the name of data file? \n");
scanf("%s", duom);
dataFile=fopen(duom, "r");
if (dataFile==NULL){
printf ("Error opening data file \n");
return 0;
};
printf("What's the name of results file? \n");
scanf ("%s", res);
resFile=fopen(res, "w");
if (resFile==NULL){
printf ("Error opening results file \n");
return 0;
};
while (fgets(linex, sizeof(linex), dataFile)) {
palindrome(linex);
}
printf ("all done!");
fclose(dataFile);
fclose(resFile);
}
void palindrome(char *linex){
int i, wordlenght, j;
j = 0;
char *wordie;
const char space[2] = " ";
wordie = strtok(linex, space);
while ( wordie != NULL ) {
wordlenght = strlen(wordie);
if (wordie[j] == wordie[wordlenght-1]) {
for (i = 0; i < strlen(wordie); i++) {
if (wordie[i] == wordie[wordlenght-1]) {
if (i == strlen(wordie)-1) {
fprintf(resFile,"");
}
wordlenght--;
}
else {
fprintf(resFile,"%s", wordie);
break;
}
}
}
else {
fprintf(resFile,"%s", wordie);
}
wordie = strtok(NULL, space);
}
}
EDIT:
Code below works as following:
input file is read char by char
if char read isn't alphanumeric, then it is written to the output file
else, the whole word is read with fscanf
if word is not a palindrome, then write to the output file
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
int is_pal(char* word) {
size_t len = strlen(word);
char* begin = word;
char* end = word + len - 1;
if (len == 1) {
return 1;
}
while (begin <= end) {
if (*begin != *end) {
return 0;
}
begin++;
end--;
}
return 1;
}
int main(void)
{
FILE* fin = fopen("pals.txt", "r");
if (fin == NULL) {
perror("fopen");
exit(1);
}
FILE* fout = fopen("out_pals.txt", "w");
if (fout == NULL) {
perror("fopen");
exit(1);
}
int ret;
char word[100];
while ((ret = fgetc(fin)) != EOF) {
if (!isalpha(ret)) {
fprintf(fout, "%c", ret);
}
else {
ungetc(ret, fin);
fscanf(fin, "%s", word);
if (!is_pal(word)) {
fprintf(fout, "%s", word);
}
}
}
fclose(fin);
fclose(fout);
return 0;
}
I've created file with following content:
cancer kajak anna sam truck
test1 abc abdcgf groove void
xyz annabelle ponton belowoleb thing
cooc ringnir
The output file :
cancer sam truck
test1 abc abdcgf groove void
xyz annabelle ponton thing
(line with two spaces)
As you can see, the number of spaces between words are the same as in the input file.
I've assumed that single word could have 100 chars maximum. If there would be longer words, reading with fscanf onto fixed-size buffer can be harmful.
Hints:
strtok() gives you a pointer to the start of delimited words but it does not
extract them or put them in their own string for you.
You need some logic to find the end of each word. The function
strlen() will tell you how many characters there are from the char*
that it gets until a null-character. If you give it a pointer to the start
of a word within a sentence it will give you the length from the start of the
word to the end of the sentence.
Breaking palindrome() into a function that loops over words in a line and a
function that returns whether or not a single word is a palindrome
may help.
Your for loop is checking each pair of letters twice. i only needs to scan over half
of the word length.
You only need a single if within palindrome(). I'm not sure why you have so many.
They're redundant.

Resources