Rename a file and save it as a another one - c

I'm trying to get a filename that exists at the beginning. After that I want to add _blabla.txt to the filename and create the another one.
Here the example. --> example.txt (what I get)
Here the what I want. --> example_blabla.txt (what I want to create)
I tried to use sprintf(filename, "%s%s", argv[1], "_blabla.txt") but the created file's name is example.txt_blabla.txt.
How can I remove extension of first filename from the filename that I created ?
Here is my code:
FILE *fp;
FILE *fp2;
char filename[300];
if (argc != 2 || argv[1] == NULL) {
printf(" You did not enter a file name! \n");
exit(-1);
}
sprintf(filename, "%s%s", argv[1], "_blabla.txt");
fp = fopen(argv[1], "r");
fp2 = fopen(filename, "w");
return 0;

Here are some suggestions:
to locate the last '.' in the string, you can use the function strrchr() from <string.h>.
to avoid undefined behavior on overlong strings, use snprintf instead of sprintf.
to copy a portion of a string with snprintf, use %.*s with an int argument before the string pointer.
Here is a modified version:
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[]) {
FILE *fp;
FILE *fp2;
char filename[300];
char *p;
int pos;
if (argc != 2) {
printf(" You did not enter a file name!\n");
return -1;
}
p = strrchr(argv[1], '.');
if (p != NULL)
pos = p - argv[1];
else
pos = strlen(argv[1]);
// Using the %.*s precision field to limit the number of characters
// copied from `argv[1]`
snprintf(filename, sizeof filename, "%.*s_blabla.txt", pos, argv[1]);
fp = fopen(argv[1], "r");
if (fp == NULL)
return 1;
fp2 = fopen(filename, "w");
if (fp2 == NULL)
return 1;
/* copy the file */
fclose(fp);
fclose(fp2);
return 0;
}

Append the following statements before and after your sprintf() call as follows:
int i;
char *pChar = NULL;
for (i = strlen(argv[1]) - 1; i >= 0: i--) {
if (argv[1][i] == '.') {
pChar = &argv[1][i];
*pChar = '\0';
break;
}
}
sprintf(filename,"%s%s",argv[1],"_blabla.txt");
if (pChar != NULL)
*pChar = '.';

the following proposed code:
demonstrates a method to extract the root name from a filename then append a set of characters.
demonstrates how to inform the user when the command line parameter is missing.
does not perform a stat() to assure the source file actually exists, That is left to the OP to include.
properly checks for I/O errors
documents why each header file is included
suggest getting the length of the argv[1] parameter, add the length of blabla.txt, add 1, then use the VLA feature of C to appropriately size the array filename[]. Note: strlen() works well for obtaining the length of a NUL terminated char array
And now, the proposed code:
#include <stdio.h> // fopen(), fclose(), perror(), fprintf(), FILE
#include <stdlib.h> // exit(), EXIT_FAILURE
#include <string.h> // strrchr(), strcat()
int main( int argc, char (argv[] )
{
FILE *fp;
FILE *fp2;
char filename[300];
if (argc != 2 )
{
fprintf( stderr, "USAGE: %s fileName\n", argv[0] );
exit( EXIT_FAILURE );
}
strcpy(filename, argv[1] );
char *ptr = strrchr( filename, '.' );
if( ptr )
{
*ptr = '\0';
}
strcat( filename, "_blabla.txt");
fp = fopen(argv[1], "r");
if( ! fp )
{
perror( "fopen for input file failed" );
exit( EXIT_FAILURE );
}
fp2 = fopen(filename, "w");
if( ! fp2 )
{
perror( "fopen for output file failed" );
fclose( fp1 );
exit( EXIT_FAILURE );
}
return 0;
}

Related

C program to print given number of lines from beginning of text file. File name and number of lines from command line argument

I'm writing a program said in this post title. I take reference at this webpage.
https://www.includehelp.com/c-programs/c-program-to-print-given-number-of-lines-of-a-file-like-head-command-in-linux.aspx
Here are the codes from that webpage.
#include <stdio.h>
int main(int argc, char * argv[])
{
FILE *fp; // file pointer
char *line = NULL;
int len = 0;
int cnt = 0;
if( argc < 3)
{
printf("Insufficient Arguments!!!\n");
printf("Please use \"program-name file-name N\" format.\n");
return -1;
}
// open file
fp = fopen(argv[1],"r");
// checking for file is exist or not
if( fp == NULL )
{
printf("\n%s file can not be opened !!!\n",argv[1]);
return 1;
}
// read lines from file one by one
while (getline(&line, &len, fp) != -1)
{
cnt++;
if ( cnt > atoi(argv[2]) )
break;
printf("%s",line); fflush(stdout);
}
// close file
fclose(fp);
return 0;
}
My problem is the getline function. Since I'm not using Linux that function's giving error in my compiler. I tried to change it to fgets function. This is my revised codes.
I got two errors in the line ' while (fgets(&line, bufferLength, fp) != -1)'.
Error: passing argument 1 of 'fgets' from incompatible pointer type.
Error: comparison between pointer and integer.
My question is - how can I modify the program using fgets? Many thanks to anyone who can work this out.
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
FILE *fp; // file pointer
char *line = NULL;
int bufferLength = 255;
int cnt = 0;
if( argc < 3)
{
printf("Insufficient Arguments!!!\n");
printf("Please use \"program-name file-name N\" format.\n");
return -1;
}
// open file
fp = fopen(argv[1],"r");
// checking for file is exist or not
if( fp == NULL )
{
printf("\n%s file can not be opened !!!\n",argv[1]);
return 1;
}
// read lines from file one by one
while (fgets(&line, bufferLength, fp) != -1)
{
cnt++;
if ( cnt > atoi(argv[2]) )
break;
printf("%s",line);
fflush(stdout);
}
// close file
fclose(fp);
return 0;
}
Your program should compile and run correctly follows:
//c program to print given number of lines from beginning of a file
//file name and number of lines must be supply as command line argument
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char * argv[])
{
FILE* fp; // file pointer
char* line = malloc(255);
int bufferLength = 255;
int cnt = 0;
if( argc < 3)
{
printf("Insufficient Arguments!!!\n");
printf("Please use \"program-name file-name N\" format.\n");
return -1;
}
// open file
fp = fopen(argv[1],"r");
// checking for file is exist or not
if( fp == NULL )
{
printf("\n%s file can not be opened !!!\n",argv[1]);
return 1;
}
// read lines from file one by one
while (fgets(line,bufferLength, fp))
{
cnt++;
if ( cnt > atoi(argv[2]) )
break;
printf("%s",line);
fflush(stdout);
}
// close file
fclose(fp);
free(line);
return 0;
}
we have two main problems, first
char * line = NULL;
line is a line of characters, a string if you want to call it that, so we must reserve enough memory to accommodate a complete line, and we do this with the malloc function, as seen in the program, the other problem we have with fgets, this function returns a pointer therefore we cannot compare the value returned by fgets with an integer, the declaration
while (fgets (line, bufferLength, fp))
is equivalent to running the loop while fgets is other than NULL. Finally we must use line instead of &line, the latter asks for the address of the line pointer, and not the address it points to.
There's no need to keep track of more than a single character. Reading full lines is overkill. Just do:
#include <stdio.h>
#include <stdlib.h>
FILE *
xfopen(const char *path, const char *mode)
{
FILE *fp = fopen(path, mode);
if( fp == NULL ) {
perror(path);
exit(EXIT_FAILURE);
}
return fp;
}
int
main(int argc, char **argv)
{
int count = argc > 1 ? strtol(argv[1], NULL, 10) : 1;
FILE *in = argc > 2 ? xfopen(argv[2], "r") : stdin;
int line = 0;
int c;
while( line < count && ( c = fgetc(in)) != EOF ) {
putchar(c);
if( c == '\n' ) {
line += 1;
}
}
}
Note that I've reversed the order of the arguments, so that stdin is read if only a count is given.

Converting a binary to char [C]

a lot of times ago, i found an extract of C code, that could read the content of an executable file and that can store it as an array of char, in another file (ex: output.txt). It should work, but when i tried it, it corrupts the output, and it can't copy exactly the content of the exe as a char without damaging it. I don't know where could be the problem.
This is my extract of code in C
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
int main(int argc, char *argv[])
{
if(argc != 3)
{
fprintf(stderr, "Usage >NameProgram firstParam Executable.exe\n");
return -1;
}
FILE *output = fopen("output.txt", "a");
[..]
char* input_file = argv[2]; //the name of the exe
FILE* f_input = fopen(input_file, "rb");
fprintf(output,"char byn[] = {\n");
unsigned long n = 0;
while(!feof(f_input))
{
unsigned char c;
if(fread(&c, 1, 1, f) == 0)
break;
fprintf(output,"0x%.2X,", (int)c);
++n;
if(n % 10 == 0)
fprintf(output,"\n");
}
fclose(f_input);
fclose(output);
//truncating file
FILE *output = fopen("output.txt", "r+");
fseek(output, -1, SEEK_END);
fprintf(output,"};\n\n");
fclose(output);
[..]
using your posted code as a guide, I produced the following:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
if(argc != 3)
{
fprintf( stderr, "USAGE: %s outFilename inFileName\n", argv[0] );
exit( EXIT_FAILURE );
}
FILE *fp_out = fopen( argv[1], "a");
FILE* fp_in = fopen( argv[2], "rb");
fprintf(fp_out, "char byn[] = {\n" );
unsigned long n = 0;
unsigned char c;
while(fread(&c, 1, 1, fp_in) == 1)
{
fprintf( fp_out,"0x%.2X,", (int)c);
++n;
if(n % 10 == 0)
fprintf( fp_out,"\n");
}
fprintf( fp_out, "};\n\n");
fclose(fp_in);
fclose(fp_out);
} // end function: main
which I ran on a few executable files
Note: I'm running Ubuntu Linux 14.04
It seems to work correctly.
As with your example, I skipped the error checking (which you should really include in your actual code.)

Cant scan file in C

I am cant seem to get my simple script to read the file. All i am trying to do is read letters into an array. I just get random characters and it is driving me crazy. I have the file in the Debug folder, what else can go wrong? I am 100 percent sure everything is correct.
Here is my code:
FILE * ifp;
ifp = fopen("letters.txt", "r");
int i;
int bound = 20;
char data[20];
for(i =0; i<bound; i++){
fscanf(ifp, "%s", &data[1]);
if (ifp == NULL){
return;
}
printf("Data %d = %c\n", i, data[i]);
}
The following code
1) checks for errors
2) compiles cleanly
3) works on a test.txt file I produced.
#include <stdio.h>
#include <stdlib.h>
#define bound (20)
int main( void )
{
FILE * ifp;
if( NULL == (ifp = fopen("letters.txt", "r") ) )
{ // then, fopen failed
perror( "fopen for letters.txt failed");
exit( EXIT_FAILURE );
}
// implied else, fopen successful
int i;
char data[bound];
for(i =0; i<bound; i++)
{
if( 1 != fscanf(ifp, "%c", &data[i]) )
{ // then fscanf failed
perror( "fscanf failed" );
exit( EXIT_FAILURE );
}
// implied else, fscanf successful
printf("Data %d = %c\n", i, data[i]);
}
return(0);
} // end function: main
Hmm could it be because
&data[1]
should be just
data
or the equivalent
&data[0]
which is likely what you intended.
?
Only other reason I can think of is, the line you are reading is greater than 20 characters and its overflowing the data array.
Have a look at this example: http://www.tutorialspoint.com/c_standard_library/c_function_fscanf.htm
Here's an example:
#include <stdio.h>
#define MAX_LINES 10
#define MAX_LINE 80
#define FILE_NAME "lines.txt"
int
main (int argc, char *argv[])
{
char lines[MAX_LINES][MAX_LINE];
FILE *fp;
int i = 0;
if (!(fp = fopen(FILE_NAME, "r"))) {
perror ("file open error");
return 1;
}
while (i < MAX_LINES) {
if (fgets (lines[i], MAX_LINE, fp)) {
printf ("Line[%d]=%s", i, lines[i]);
i++;
} else {
printf ("End of file: closing %s\n", FILE_NAME);
break;
}
}
fclose (fp);
return 0;
}
Sample output:
$ gcc -o x1 -Wall -pedantic -g x1.c
$ ./x1
Line[0]=Come and listen to my story
Line[1]='Bout a man named Jed
Line[2]=Poor mountaineer,barely kept his fam'ly fed
End of file: closing lines.txt
Note:
We're reading a line at a time
We're reading each line into an array
We define the #/elements in the array (MAX_LINES) and the maximum size of each string (MAX_LINE) ahead of time
We check for "file open error" (and return "non-zero" accordingly)
We use "fgets()" to safely read a line (without risking a buffer overrun).
If you wanted to read a character at a time, the program could be as simple as:
char string[MAX_LINE], *c;
...
if (!(fp = fopen(FILE_NAME, "r"))) {
perror ("file open error");
return 1;
}
...
c = string;
while ((*c = fgetc (fp)) != EOF)
c++;
One problem with the second example is that it doesn't check for string length >> MAX_LINE. But hopefully it helps give you some ideas...

Reading line by line from a file in C

What I am trying to do is print out the contents of a file line by line. I run the program in terminal by doing: ./test testText.txt. When I do this, random characters are printed out but not what is in the file. The text file is located in the same folder as the makefile. What's wrong?
#include <stdio.h>
FILE *fp;
int main(int argc, char *argv[])
{
char line[15];
fp = fopen(*argv, "r");
while((fgets(line, 15, fp)) != NULL)
{
printf(line);
printf("\n");
}
}
When I do this, random characters are printed out but not what is in the file
These characters are not random, and in fact they are coming from a file. It's not the file that you are trying to read, though - it's the executable file which you are running.
*argv represents the name of the executable; add this line to see what's in *argv:
printf("%s\n", *argv);
The actual command line arguments start at argv[1], so you need
fp = fopen(argv[1], "r");
The first argument passed on the command line is at argv[1], while *argv refers to argv[0]. argv[0] contains the filename of the executable - you are printing out the content of the executable.
The following code prints out the entire argv[] array, then reads your file and prints it.
#include <stdio.h>
int main( int argc, char *argv[] )
{
for( int i = 0; i < argc; i++ )
{
printf( "argv[%d] : %s\n", i, argv[i] ) ;
}
if( argc >= 2 )
{
FILE* fp = fopen( argv[1], "r" ) ;
if( fp != NULL )
{
char line[15];
while( fgets( line, sizeof(line), fp ) != NULL )
{
printf( "%s", line ) ;
}
}
}
return 0 ;
}
Note that fgets() will read an entire line including the , so there is no need to print '\n', especially because with only 15 characters, your line buffer may well not contain an entire line. Note also the tighter localisation of variables - your code needlessly made fp global.
Other refinements are the safe use of the array size rather than literal 15, and the use of a literal constant string for the format specifier. You should avoid passing a variable string for the printf() format string - if your input itself contains format specifiers, printf() will try to read data from arguments that do not exist with undefined results.
Q: What's wrong?
A humble critique:
#include <stdio.h>
FILE *fp; // Perhaps this should be declared inside main?
int main(int argc, char *argv[])
{
char line[15]; // Are the file lines all 14 characters or less? (seems small)
fp = fopen(*argv, "r"); // Opening the binary executable file (argv[0])? Intereting.
// Should check here to ensure that fopen() succeeded.
while((fgets(line, 15, fp)) != NULL)
OK... well, remember that this isn't a text file.. it's an executable (due to *argv). This will read some wacky (but not random) characters from the executable.
{
printf(line); // Bad practice. Should be: printf("%s", line);
Ok... now print the wacky characters?
printf("\n"); // Redundant. The '\n' characters will be supplied in 'line'.
}
// fclose() call missing.
// Integer return value for main() is missing.
}
Here is (perhaps) what was actually intended:
#include <stdio.h>
#include <errno.h>
int main(int argc, char *argv[])
{
int rCode = 0;
FILE *fp = NULL;
char line[255+1];
if(argc != 2)
{
printf("Usage: %s {filepath}\n", *argv);
goto CLEANUP;
}
errno=0;
fp = fopen(argv[1], "r");
if(NULL == fp)
{
rCode=errno;
fprintf(stderr, "fopen() failed. errno:%d\n", rCode);
goto CLEANUP;
}
while(fgets(line, sizeof(line), fp)) /* --As per 'chux' comment */
printf("%s", line);
CLEANUP:
if(fp)
fclose(fp);
return(rCode);
}
Or, if the intent is truly to print the content of the executable, perhaps this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
int main(int argc, char *argv[])
{
int rCode = 0;
FILE *fp = NULL;
off_t offset = 0;
errno=0;
fp = fopen(*argv, "r");
if(NULL == fp)
{
rCode=errno;
fprintf(stderr, "fopen() failed. errno:%d\n", rCode);
goto CLEANUP;
}
for(;;)
{
char line[16];
size_t bytesRead;
int index;
char ascii[16+1];
memset(ascii, 0, sizeof(ascii));
bytesRead = fread(line, 1, sizeof(line), fp);
if(0==bytesRead)
break;
printf(" %08zX | ", offset);
for(index=0; index < bytesRead; ++index)
{
printf("%02hhX%c", line[index], 7==index ? '-' : ' ');
ascii[index] = isprint(line[index]) ? line[index] : '.';
}
printf("%*s %s\n", (16 -index) * 3, "", ascii);
offset += bytesRead;
}
if(errno)
{
rCode=errno;
fprintf(stderr, "fgets() failed. errno:%d\n", errno);
}
CLEANUP:
if(fp)
fclose(fp);
return(rCode);
}
your file name found at index 1 of argv.
if (argc <= 1) {
printf("no file was given\n");
exit(-1);
}
// open file from argv[1]
// ...

File manipulations in C

I am using a simple 'C' code to do the following:
1) Read from a .txt file.
2) Based on the string present in the .txt file, a directory will be created.
I am not able to perform step-2, as I am not clear with type conversions.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <direct.h>
int main()
{
char ch, file_name[25];
FILE *fp;
//printf("Enter the name of file you wish to see\n");
//gets(file_name);
fp = fopen("input.txt","r"); // read mode
if( fp == NULL )
{
perror("Error while opening the file.\n");
exit(EXIT_FAILURE);
}
printf("The contents of %s file are :\n", file_name);
while( ( ch = fgetc(fp) ) != EOF )
printf("%c",ch);
if( _mkdir(ch ) == 0 )
{
printf( "Directory successfully created\n" );
printf("\n");
}
fclose(fp);
return 0;
}
Here is the error:
*error #2140: Type error in argument 1 to '_mkdir'; expected 'const char *' but found 'char'.*
YES, compiler is right.
You are passing a char c to _mkdir, instead of a string.
You should read the string from file and store it to file_name (I guess you forget) and then
_mkdir(file_name);
See below:
#include <stdio.h>
#include <stdlib.h>
#include <direct.h>
int main()
{
char file_name[25];
FILE *fp;
fp = fopen("input.txt", "r"); // read mode
if (fp == NULL)
{
perror("Error while opening the file.\n");
exit(EXIT_FAILURE);
}
fgets(file_name, 25, fp);
_mkdir(file_name);
fclose(fp);
return 0;
}
It's because you only have a single char (the c in fgetc stands for char) while _mkdir wants a string (i.e. char *).
You should probably use fgets instead to read the input.
If you dont want to use fgets , then you can use this.
#include <stdio.h>
#include <stdlib.h>
#include <direct.h>
int main()
{
char file_name[25];
String str;
FILE *fp;
char ch;
int i=0;
fp = fopen("input.txt", "r"); // read mode
if (fp == NULL)
{
perror("Error while opening the file.\n");
exit(EXIT_FAILURE);
}
while( ( ch = fgetc(fp) ) != EOF ){
printf("%c",ch);
file_name[i];
i++
}
str=file_name;
_mkdir(str);
fclose(fp);
return 0;
}

Resources