Issue in reading specific portion of File - c

I am trying to extract and print a specific portion of text from a file at a given time.I used ftell() and fseek() to achieve this.
#include <stdio.h> //// include required header files
#include <string.h>
int main()
{
FILE *fp = fopen("myt", "w+");
if (fp == NULL) //// test if file has been opened sucessfully
{
printf("Can't open file\n");
return 1; //// return 1 in case of failure
}
char s[80];
printf("\nEnter a few lines of text:\n");
while (strlen(gets(s)) > 0) //user inputs random data
{ //till enter is pressed
fputs(s, fp);
fputs("\n", fp);
}
long int a = ftell(fp);
fputs("this line is supposed to be printed only ", fp);//line to be
// displayed
fputs("\n", fp);
fputs("this line is also to be printed\n",fp); //line to be
//displayed
fputs("\n",fp);
long int b = ftell(fp);
fputs("this is scrap line",fp);
fputs("\n",fp);
rewind(fp);
fseek(fp, a, SEEK_CUR); //move to the starting position of text to be
//displayed
long int c=b-a; //no of characters to be read
char x[c];
fgets(x, sizeof(x), fp);
printf("%s", x);
fclose(fp);
return 0; //// return 0 in case of success, no one
}
I tried using this approach but the program just prints the first line.The output is as follows:
this line is supposed to be printed only
I want to print both the lines intended to be printed.Please suggest an approach.

I think your intent for the reading portion was
rewind(fp);
fseek(fp, a, SEEK_CUR); //move to the starting position of text to be
//displayed
long int c=b-a; //no of characters to be read
char x[c+1];
int used = 0;
while(ftell(fp) < b)
{
fgets(x+used, sizeof(x)-used, fp);
used = strlen(x);
}
printf("%s", x);
Notes:
I added +1 to the allocation of your buffer x because fgets adds
null termination.
I'm not 100% sure you don't want fflush(fp) between the writes and the reads.

Related

Chose random a word from txt file and mark it as chosen in C

I want to randomly extract a word from the text file and mark it as chosen.(I want to add a * at the end of the word)
I can extract the words random but when I want to mark the word as chosen (add '*') the * character is added at the end of the file and not at the end of the chosen word. I don't know why.
Does anyone have an idea?
#include <stdlib.h>
#include<stdio.h>
#include <time.h>
#include <unistd.h>
int main(void)
{
char secret[50];
unsigned long fileLen;
srand(time(NULL));
FILE *fp = fopen("input.txt", "a+");
if( fp == NULL ){
fprintf(stderr, "No such file or directory: %s\n");
return 1;
}
//Get file length
fseek(fp, 0, SEEK_END);
fileLen=ftell(fp);
fseek(fp, 0, SEEK_SET);
printf("fileLen --------->%ld\n", fileLen);
do{
// generate random number between 0 and filesize
unsigned long random = (rand() % fileLen) + 1;
// seek to the random position of file
fseek(fp, random, SEEK_SET);
// get next word in row ;)
printf("Random ------->%ld\n", random);//testing purpose
printf("ftell --------->%ld\n", ftell(fp));
int result = fscanf(fp, "%*s %s", secret);
printf("Chosen word is: %s \n", secret);
int len = strlen(secret);
if(result)
{
fseek(fp, len, SEEK_CUR);
fputc('*', fp); // put a '*' at the end of the word that was chosen
}
if( result != 0 )
break;
} while(1);
fclose(fp);
}
Using fseek to get the length is good, and logically, it stops at the end of the file, the issue is that is stays there (that's why * is in the end), so after using it, you are at the end of the file, use rewind(fp) to return to the beginning of the file after using fseek(fp) to get its length.
Also, read Eugene Sh's comment.

Displaying portion of text from text file in C

I have a text file and I wanted to extract only a specific part of it at a particular time.For that ,I used ftell() while writing to note the start and end positions and then use fseek() to jump to that particular location.
int main()
{
FILE *fp=fopen("myt","w+");
char s[80];
printf ( "\nEnter a few lines of text:\n" ) ;
while ( strlen ( gets ( s ) ) > 0 ) //user inputs random data
{ //till enter is pressed
fputs ( s, fp ) ;
fputs ( "\n", fp ) ;
}
long int a=ftell(fp);
fputs("this line is supposed to be printed only ",fp);//line to be
// displayed
fputs("\n",fp);
long int b=ftell(fp);
printf("start is %ld",a);
printf("\nend is %ld",b);
printf("here is the data...\n");
rewind(fp);
fseek(fp,a,SEEK_CUR); //move to the starting position of text to be
//displayed
char x[1000];
fgets(x,b-a,SEEK_CUR);
printf("%s",x);
return 1;
}
I tried this but face a unexpected abnormal termination of program.Please guide me as to how correctly implement my task.
You want this:
Comments starting with //// are mine
#include <stdio.h> //// include required header files
#include <string.h>
int main()
{
FILE *fp = fopen("myt", "w+");
if (fp == NULL) //// test if file has been opened sucessfully
{
printf("Can't open file\n");
return 1; //// return 1 in case of failure
}
char s[80];
printf("\nEnter a few lines of text:\n");
while (strlen(gets(s)) > 0) //user inputs random data
{ //till enter is pressed
fputs(s, fp);
fputs("\n", fp);
}
long int a = ftell(fp);
fputs("this line is supposed to be printed only ", fp);//line to be
// displayed
fputs("\n", fp);
long int b = ftell(fp);
printf("start is %ld", a);
printf("\nend is %ld", b);
printf("here is the data...\n");
rewind(fp);
fseek(fp, a, SEEK_CUR); //move to the starting position of text to be
//displayed
char x[1000];
fgets(x, sizeof(x), fp); //// the usage of fgets was totally wrong
printf("%s", x);
return 0; //// return 0 in case of success, no one
}
Disclaimer: The first part reading the strings using gets is still sloppy, you should never use gets, it's an old deprecated function. Use fgets instead.

fprintf() on a new line of a file

How i can make a new line at the end of a file to fprintf() user inputed text?
My code right now is this:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int lines;
int number;
FILE *fp;
printf("Insert random number: ");
scanf("%d", &number);
fp = fopen("textfile.txt", "r");
char ch;
while((ch=fgetc(fp))!=EOF)
{
if (ch=='\n') {
lines++;
}
}
fclose(fp);
fopen("textfile.txt", "ab");
fseek(fp, lines, SEEK_SET);
fprintf(fp,"%d", number);
fclose(fp);
}
You just need to add a '\n' to the fprintf() like this
fprintf(fp,"\n%d", number)
/* ^ */
but you also need a lot of error checking, for instance fopen() returns NULL when it fails to open the file.
Your code is actually very broken, you count the lines in the file opened with "r", i.e. for reading, then you call fopen() with "ab" but discard the return value, you then fseek() the number of lines, and fseek() is for the number of characters not lines, then you write to the closed fp pointer, because
fopen("textfile.txt", "ab"); /* you don't assign the return value anywhere */
fseek(fp, lines, SEEK_SET); /* this is the same pointer you `fclosed()' */
/* ^ this will not seek to the end of the file */
fprintf(fp,"%d", number); /* here `fp' is still invalid */
Test this
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *file;
const char *filename = "textfile.txt";
printf("Insert a number: ");
if (scanf("%d", &number) != 1)
{
fpritnf(stderr, "invalid input, expected a number\n");
return -1;
}
file = fopen(filename, "a");
if (file == NULL)
{
fprintf(stderr, "cannot open %s for appending\n", filename);
return -1;
}
fprintf(file, "\n%d", number);
fclose(file);
return 0;
}
You don't need to fseek() if you open with "a" because new content is appended to the end of the file, you need a '\n' before the user input if there was no '\n' in the file or if you want to force the new value in a new line.
You don't need the "b" in the mode string, because you are writing text to the file, and on some platforms the file will have issues when you open it in a text editor.

How output text when decrypting a hex? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
i am trying to decrypt the hex string: 0440 04b4 04d0 04d0 04dc 03a0 047c 04dc 04e8 04d0 04b0 03a4
It should once decrypted properly read hello world!
however i cannot get it to output the text. instead i get a list of integers. does anyone have any ideas as to how to fix this?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main (int argc, char **argv)
{
char file_name[25];
char c; //Variable to hold current character
int sz; //Length of file therefore size of array
FILE *fp;
FILE *fw;
int flag = 1;
while (flag)
{
printf("enter the name of the file you wish to decrypt\n");
fgets(file_name, sizeof file_name, stdin); //fgets safer than gets, prevents infinite input
printf("Reading: %s.....\n", file_name); //debug print, can remove
strtok(file_name, "\n"); //fgets potentially leaves \n on file name, this removes
fp=fopen(file_name,"rt"); //file is opened
fw = fopen("revertedfile.txt", "w"); //oens write file
if( fp == NULL ) //checks if file empty/doesn't exist
{
perror("Error while opening the file.\n");
exit(EXIT_FAILURE);
}
//Following code finds length of file by seeking, then resets the file point to the start
fseek(fp, 0L, SEEK_END);
sz = ftell(fp);
printf("Length of file is: %i\n",sz); // Debug print, can delete
fseek(fp, 0L, SEEK_SET);
int data[sz]; //Init array based on file length
int i = 0; //Counter set to 0
while((c=fgetc(fp))!=EOF) //While haven't reached end of file.
{
int ic = (int)c - 200; //minus 200 to the ascii code
//printf("ASCI Code + 100 = %i\n", ic); //debug print
//Could do bit shift before adding to array, I Guess
data[i] = ic; //Add ASCII code to array at i
data[i] = data[i] >> 2; //Bit shift
//Debug print, shows what's happening
int test = data[i];
printf("%i\n", data[i]);
fprintf(fw, "%i\n", data[i]);
//printf("Added %i to the array at point %d\n", test, i);
i++; //Increment pointer for array
}
fclose(fp); //Always close file
fclose(fw); // closes write file
}
return 0;
}
This is the encryption code
printf("enter name of the file you wish to encrypt\n");
fgets(file_name, sizeof file_name, stdin); //fgets safer than gets, prevents infinite input
printf("Reading: %s.....\n", file_name); //debug print, can remove
strtok(file_name, "\n"); //fgets potentially leaves \n on file name, this removes
fp = fopen(file_name,"rt"); //file is opened
fw = fopen("output.txt", "w"); //oens write file
if( fp == NULL ) //checks if file empty/doesn't exist
{
perror("Error while opening the file.\n");
exit(EXIT_FAILURE);
}
//Following code finds length of file by seeking, then resets the file point to the start
fseek(fp, 0L, SEEK_END);
sz = ftell(fp);
printf("Length of file is: %i\n",sz); // Debug print, can delete
fseek(fp, 0L, SEEK_SET);
int data[sz]; //Init array based on file length
int i = 0; //Counter set to 0
while((c=fgetc(fp))!=EOF) //While haven't reached end of file
{
printf("Current char: %c\n",c); //Debug print
int ic = (int)c + 200; //Add 200 to the ascii code
//printf("ASCI Code + 100 = %i\n", ic); //debug print
//Could do bit shift before adding to array, I Guess
data[i] = ic; //Add ASCII code to array at i
data[i] = data[i] << 2; //Bit shift
//Debug print, shows what's happening
int test = data[i];
printf("%04x ", data[i]);
fprintf(fw, "%04x ", data[i]);
//printf("Added %i to the array at point %d\n", test, i);
i++; //Increment pointer for array
}
fclose(fp); //Always close file
fclose(fw); // closes write file
//Debug
int test2 = data[1];
printf("The new file is named output.txt");
If you want to decrypt it, you need to know how it was encrypted (well, that still might not be enough). If you just need to print the character each ASCII code represents, you just need to tell printf that by using %c instead of %i.

Using fread and fwrite in one stream at the same time caused a problem

This program want to read from a file. the content in the file is the string "Hello, world". then judge each character of the string to see if the character greater than or equal to the const character 'e', if the character meet the condition, than change the character to its previous character in the alphabetical order (eg. 'b' change to 'a', 'e' change to 'd'). Finally, output the changed file content to the screen.
The question is how do the fwrite and fread work? why can't I get rid off the variable pos2 to simplify the expression. If anyone can help, thanks a lot!
#include <stdio.h>
int main()
{
FILE *fp;
char s[20];
char t[20];
char transfer;
int i;
int pos; // storing the position of the file before reading from the file
int pos1; // check the position of the file
int pos2; // storing the position of the file after reading from the file
#pragma region create a file named "Hello", write "Hello, world" into the file, close it
if ((fp = fopen("Hello", "wb") )== NULL)
{
printf("can't open file\n");
exit(0);
}
strcpy(s, "Hello, world");
fwrite(s, sizeof(char)*20, 1, fp);
fseek(fp, 0, SEEK_SET);
fclose(fp);
#pragma endregion create a file named "Hello", write "Hello, world" into the file, close it
#pragma region read from the file named "Hello", deal with its current, write the change into the file.
if ((fp = fopen("Hello", "rb+")) == NULL )
{
printf("can't open file\n");
exit(1);
}
i = 0;
while(i < 20)
{
// 提问,该处为何不能利用fwrite的自动定位免去注释掉的语句行(即使用了pos2的语句行)。
// Here is the problem. since the fread and fwrite function can move the position of the
// file, I think I can get rid off the following commented two sentences with the
// variable pos2 in it
pos = ftell(fp); // storing the position before reading from file
fread(&transfer, sizeof(char), 1, fp); // the position of the file moved to the next char
// pos2 = ftell(fp); // storing the position after reading from file
pos1 = ftell(fp);
if (transfer >= 'e') // if the character greater or equal to 'e' minus 1.
{
transfer -= 1;
}
fseek(fp, pos, SEEK_SET); // back to the position where the character is read to change the char
fwrite(&transfer, sizeof(char), 1, fp);// the position of the file moved to the next char
// fseek(fp, pos2, SEEK_SET); //
pos1 = ftell(fp);
i++;
}
fseek(fp, 0, SEEK_SET);
fclose(fp);
#pragma endregion read from the file named "Hello", deal with its current, write the change into the file.
#pragma region read from the file named "Hello", output the changed string
if((fp = fopen("Hello", "rb")) == NULL)
{
printf("Can't open file\n");
exit(2);
}
fread(t, sizeof(char)*20, 1, fp);
printf("The output is: %s \n", t);
// the right output is (the two sentences above with pos2 in it is commented) :
// The output is: Hdkkn,vnqkd
// the wrong output is (the two sentences above with pos2 in it isn't commented):
// The output is: Hddddddddddddddddddd烫烫烫烫Hello, world
fseek(fp, 0, SEEK_SET);
fclose(fp);
#pragma endregion read from the file named "Hello", output the changed string
system("pause");
}
I didn't actually get the point why you are trying to comment in/out the 2 lines. Because nothing changes whether you comment them in or comment them out. You have already got rid of pos2 in your code (which is what you are asking).
So if you use the following code for your while loop
pos = ftell(fp); // storing the position before reading from file
fread(&transfer, sizeof(char), 1, fp);
pos1 = ftell(fp);
if (transfer >= 'e') // if the character greater or equal to 'e' minus 1.
{
transfer -= 1;
}
fseek(fp, pos, SEEK_SET);
fwrite(&transfer, sizeof(char), 1, fp);
i++;
then you get "The output is: Hdkkn,vnqkd" which is the expected result.
You could also take each line from the file to an array and make operations on it then write it back to the file. By this way, it could be more generic and you don't have to use magic numbers like "20".
EDIT:
I use gcc 4.5.2 on my linux platform. I don't want to comment on other platforms but as I mentioned before you could take the line to a buffer and then after operation you could write it back. You could try to replace the following code with your while loop:
char line[20] = {0};
fread(line, sizeof(char), 20, fp);
for(i = 0; i < strlen(line); i++)
{
if(line[i] >= 'e')
line[i] -= 1;
}
fseek(fp, 0, SEEK_SET);
fwrite(line, sizeof(char), strlen(line), fp);
By this way you could get rid of many variables. It is your choice.

Resources