How to copy file in buffer without a string - c

I would like to copy a file in a buffer without a certain string
Here's the code
void remove_line(FILE *fp, char *string, char *output) {
char buff[6];
output = malloc(500);
int i = 0;
while (fgets(buff, 6, fp) != NULL) {
char temp[6];
strcpy(temp, buff);
temp[strcspn(temp, "\n")] = 0;
if (strcmp(temp, string) != 0) {
memcpy(output + i * 6, buff, 6);
i++;
}
}
printf("%s", output);
}
int main(int argc, char *argv[])
{
FILE *f;
f = fopen("file", "a+");
char *output = NULL;
char line[] = "hello";
remove_line(f, line, output);
fclose(f);
}
and the file contains :
hello
world
My goal is to only have "world" in buffer, but currently I have nothing.
Thanks you !

Related

delimiter in C without built-in string functions

in today task i had to implement the function "my_split" that is based on pointers and accessing addresses, I'm having a little bit of trouble with "catching" all of the content from the file into the output.
this is my function:
void my_split(const char *source, char *first, char *second, const char delim){
int ree = 1;
while(*source != '\n'){
if(*source == delim){
ree = 0;
*source++;
}
else{
if(ree == 1){
*first++ = *source++;
}
else {
*second++ = *source++;
}
}
}
*first = '\0';
*second = '\0';
}
Main function:
int main(void){
int max_n = 200;
char source[max_n];
char strA[max_n];
char strB[max_n];
int T;
scanf("%d%*c", &T);
for(int i = 0; i < T; i++){
fgets (source, max_n, stdin);
my_split(source, strA, strB, ';');
printf("First: %s\n", strA);
printf("Second: %s\n", strB);
}
}
^^^ teacher gave us this one.
TXT FILE:
2
2345.454;6737.98
this is the line;splitted by semicolon
My output is:
First:
Second:
First: 2345.454
Second: 6737.98
The desired output is:
First: 2345.454
Second: 6737.98
First: this is the line
Second: splitted by semicolon
I'm trying to make above function, but It didn't workout, well it works half-succesfull
Your function seem to work. Try it like this...
#include <stdio.h>
void my_split(const char *, char *, char *, const char);
int main() {
FILE* fp;
fp = fopen("data.txt", "r");
if (NULL == fp) {
printf("file can't be opened \n");
return 0;
}
char source[100];
while (fgets(source, 100, fp) != NULL) {
char first[100] = "", second[100] = "";
my_split(source, first, second, ';');
printf("First: %s\n", first);
printf("Second: %s\n", second);
}
// Closing the file
fclose(fp);
return 0;
}
void my_split(const char *source, char *first, char *second, const char delim){
int ree = 1;
while(*source != '\n'){
if(*source == delim){
ree = 0;
*source++;
}
else{
if(ree == 1){
*first++ = *source++;
}
else {
*second++ = *source++;
}
}
}
*first = '\0';
*second = '\0';
}
It outputs:
First: 2
Second:
First: 2345.454
Second: 6737.98
First: this is the line
Second: splitted by semicolon

adding char into an array and returning

Im new to c and am trying to understand pointers.
here I am opening a file and reading the lines given. Im trying to append these lines into an array and return it from the function. I dont seem to be appending or accessing the array correctly. output[count] = status; gives an error with mismatched char and char *.
Im essentially trying to get an array with a list of words given by a file where each element in the array is a word.
char *fileRead(char *command, char output[255]) {
int count = 0;
char input[255];
char *status;
FILE *file = fopen(command, "r");
if (file == NULL) {
printf("Cannot open file\n");
} else {
do {
status = fgets(input, sizeof(input), file);
if (status != NULL) {
printf("%s", status);
strtok(status, "\n");
// add values into output array
output[count] = status;
++count;
}
} while (status);
}
fclose(file);
return output;
}
I access fileRead via:
...
char commandArray[255];
char output[255];
int y = 0;
char *filename = "scriptin.txt";
strcpy(commandArray, fileRead(filename, output));
// read from array and pass into flag function
while (commandArray[y] != NULL) {
n = flagsfunction(flags, commandArray[y], sizeof(buf), flags.position, &desc, &parentrd, right, left, lconn);
y++;
...
Example of Read from file Line by line then storing nonblank lines into an array (array of pointer to char (as char*))
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//for it does not exist because strdup is not a standard function.
char *strdup(const char *str){
char *ret = malloc(strlen(str)+1);
if(ret)
strcpy(ret, str);
return ret;
}
//Read rows up to 255 rows
int fileRead(const char *filename, char *output[255]) {
FILE *file = fopen(filename, "r");
if (file == NULL) {
perror("Cannot open file:");
return 0;
}
int count = 0;
char input[255];
while(count < 255 && fgets(input, sizeof(input), file)) {
char *line = strtok(input, "\n");
if(line)//When it is not a blank line
output[count++] = strdup(line);//Store replica
}
fclose(file);
return count;
}
int main(void){
char *output[255];//(`char *` x 255)
int number_of_read_line = fileRead("data.txt", output);
for(int i = 0; i < number_of_read_line; ++i){
printf("%s\n", output[i]);
free(output[i]);//Discard after being used
}
return 0;
}

Character array elements get replaced when using printf

I am taking the lines from a text file and storing the lines in an array. Then I am splitting the lines into separate words and storing them in another array. But I have a problem with the words stored.
Text file content:
ls -l hahaha
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *trim (char *s) {
int i = strlen(s)-1;
if ((i > 0) && (s[i] == '\n'))
s[i] = '\0';
return s;
}
int main(int argc, char *argv[]){
FILE *fp;
char *output = NULL;
fp= fopen("ints.txt", "r");
//fscanf and fprintf is used for files and is same is printf and scanf
fprintf(fp, "Testing...\n");
//fgetsc for single character in file and fputc to write
//
size_t len = 0;
ssize_t read;
const char s[2]=" ";
char *token;
char line[256];
char *lines[10];
char *eof;
char *args[10];
//=====nulling the array lines====
for(int p=0; p<10; p++)
{
lines[p]=NULL;
}
int i=0;
if (fp == NULL)
{
exit(EXIT_FAILURE);
}
else
{
while(fgets(line, 256, fp)!= NULL)
{
lines[i] = strdup(line);
//printf("%s", lines[i]);
i++;
}
}
fclose(fp);
int k=0;
for(int j=0; j<9; j++)
{
if(lines[j]!=NULL)
{
token =strtok(lines[j], s); //s is the delimiter
while(token != NULL)
{
trim(token);
//printf("%s\n", token);
args[k] = token;
token = strtok(NULL,s);
k++;
}
}
}
printf("%s\n",args[0]);
printf("%s\n", args[1]);
printf("%s\n", args[2]);
printf("%s something\n", args[0]);
printf("%s something\n" , args[2]);
printf("program done\n");
}
Output:
ls
-l
hahaha
ls something
something //the hahaha part disappears for the last printf**
program done

File CaesarShift Crypto

I'm trying to crypt a file using ceasarshift, a new file called .enc is being created but it's empty.
Here's my code :
#include <stdio.h>
#include <string.h>
char* getFileExtension(const char*);
int main(int argc, char *argv[])
{
const int shift = (int)argv[1];
int byte;
const char *fileName = (char*)argv[2];
char *fileExtension = getFileExtension(fileName);
char *newFileName = (char*)fileName;
FILE *f_in;
FILE *f_out;
f_in = fopen(fileName, "r");
if (strcmp(fileExtension, "enc") == 0)
{
// We want to decrypt the file
strcat(newFileName, ".dec");
f_out = fopen(newFileName, "w");
while ((byte = fgetc(f_in) != EOF))
{
fputc(byte - shift, f_out);
}
}
else
{
// We want to encrypt the file
strcat(newFileName, ".enc");
f_out = fopen(newFileName, "w");
while ((byte = fgetc(f_in) != EOF))
{
fputc(byte + shift, f_out);
}
}
fclose(f_in);
fclose(f_out);
return 0;
}
char* getFileExtension(const char *fileName)
{
char *extension;
int foundExtension = 0;
while (*fileName)
{
if (foundExtension == 1)
{
*extension++ = *fileName++;
}
if (*fileName == '.')
{
foundExtension = 1;
}
fileName++;
}
return extension;
}
I've made a txt file named CryptoFile which contains the following text :
This is a crypto test file !
This is the parameters I sent in the console when running the exe :
FileCaesarShift.exe 15 CryptoFile
So the shift is 15, the file to encrypt/decrypt is called "CryptoFile"
although a file called CryptoFile.enc is being created it's simply empty.
Can someone tell me what I did wrong ?
Ok I've found out that I need to pass CryptoFile.txt including the ".txt" but I wish to remove it from the name of the new files that will be created so instead of creating CryptoFile.txt.enc I want only CryptoFile.enc so I made a removeExtension function but my program crashes , here's the new code :
#include <stdio.h>
#include <string.h>
char* getFileExtension(const char*);
void removeFileExtension(char*);
int main(int argc, char *argv[])
{
const int shift = (int)argv[1];
int byte;
const char *fileName = (char*)argv[2];
char *fileExtension = getFileExtension(fileName);
char *newFileName = (char*)fileName;
removeFileExtension(newFileName);
printf("newfilename value is %s", *newFileName);
FILE *f_in;
FILE *f_out;
f_in = fopen(fileName, "r");
if (strcmp(fileExtension, "enc") == 0)
{
// We want to decrypt the file
strcat(newFileName, ".dec");
f_out = fopen(newFileName, "w");
while ((byte = fgetc(f_in)) != EOF)
{
fputc(byte - shift, f_out);
}
}
else
{
// We want to encrypt the file
strcat(newFileName, ".enc");
f_out = fopen(newFileName, "w");
while ((byte = fgetc(f_in)) != EOF)
{
printf("byte is %d\n", byte);
fputc(byte + shift, f_out);
}
}
fclose(f_in);
fclose(f_out);
return 0;
}
char* getFileExtension(const char *fileName)
{
char *extension;
int foundExtension = 0;
while (*fileName)
{
if (foundExtension == 1)
{
*extension++ = *fileName++;
}
if (*fileName == '.')
{
foundExtension = 1;
}
fileName++;
}
return extension;
}
void removeFileExtension(char *fileName)
{
while (*fileName)
{
if (*fileName == '.')
{
*fileName == '\0';
break;
}
fileName++;
}
}
LATEST EDIT :
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void copyFileExtension(char*, char*);
int getFileNameLengthWithoutExtension(char*);
int getFileExtensionLength(char*);
void copyFileNameWithoutExtension(char*, char*);
int main(int argc, char *argv[])
{
int shift = atoi(argv[1]);
int byte;
char *fileName = (char*)argv[2];
char *fileExtension = malloc(getFileExtensionLength(fileName) + 1);
copyFileExtension(fileExtension, fileName);
char *newFileName = malloc(getFileNameLengthWithoutExtension(fileName) + 5);
copyFileNameWithoutExtension(newFileName, fileName);
FILE *f_in;
FILE *f_out;
f_in = fopen(fileName, "r");
if (strcmp(fileExtension, "enc") == 0)
{
// We want to decrypt the file
puts("dec");
strcat(newFileName, ".dec");
f_out = fopen(newFileName, "w");
while ((byte = fgetc(f_in)) != EOF)
{
fputc(byte - shift, f_out);
}
}
else
{
puts("enc");
// We want to encrypt the file
strcat(newFileName, ".enc");
f_out = fopen(newFileName, "w");
while ((byte = fgetc(f_in)) != EOF)
{
fputc(byte + shift, f_out);
}
}
fclose(f_in);
fclose(f_out);
return 0;
}
void copyFileExtension(char *fileExtension, char *fileName)
{
char *token = strtok(fileName, ".");
token = strtok(NULL, ".");
strcpy(fileExtension, token);
}
int getFileNameLengthWithoutExtension(char *fileName)
{
if (*fileName && *fileName != '.')
{
return 1 + getFileNameLengthWithoutExtension(++fileName);
}
return 0;
}
int getFileExtensionLength(char *fileName)
{
int foundExt = 0;
int len = 0;
while(*fileName)
{
if (foundExt == 1)
{
len++;
}
if (*fileName == '.')
{
foundExt = 1;
}
fileName++;
}
printf("ext len is %d\n", len);
return len;
}
void copyFileNameWithoutExtension(char* dest, char *source)
{
char *fileNameWithoutExtension = strtok(source, ".");
strcpy(dest, fileNameWithoutExtension);
}
Here are a few things one can notice at a quick glance:
const int shift = (int)argv[1] does not convert the input argument to the integer value 15. Rather it casts the char* pointer in argv[1] (that is the address) into an int and assigns that (typically quite large) value to shift. To actually convert the input argument into an int consider using atoi.
you are not allocating memory for newFileName, and later writing possibly past the allocated length of the "constant" input argv[2] which newFileName points to (which results in undefined behavior).
Assuming the program doesn't crash before that, the operator precedence rule between = and != makes your while loop arguments equivalent to byte = (fgetc(f_in) != EOF). So before you reach EOF, byte == 1. If you had a shift of 15 you wind up creating a file full of unreadable control characters (ascii character 16). Given the unpredictable shift from the first bullet, who knows what is actually going to be written to file.
Though these are probably not your specific errors, the following could also cause problem:
You are also not checking whether the files were opened successfully before using them
Have you consider what would happen for letters that are near the end of the valid characters?

Reading from a file into an array of chars

I'm trying to read a list of strings from a file to an array.
in file it looks like this
ItemOne
ItemTwo
ItemThree etc.
I declared an array as:
char** array;
and file as:
FILE *read;
This is what I came up with:
{
i = 0;
printf("Type in the name of the file\n");
scanf("%s", &name);
read = fopen(name, "r");
if (read == NULL)
{
perror("Doesn't work");
return 1;
}
else
{
array = malloc(100 * sizeof(*array));
while (!feof(read))
{
array[i] = malloc(32 * sizeof(*array[i]));
fscanf(read, "%s", &array[i]);
i++;
}
}
}
Tt compiles, but when I try to display the array it's empty. Any ideas?
while (!feof(read))
{
array[i] = malloc(32 * sizeof(*array[i]));
fscanf(read, "%s", array[i]); //You should pass a pointer to a pointer to array of chars
i++;
}
I hope it'll work...
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
long GetFileSize(FILE *fp){
long fsize = 0;
fseek(fp,0,SEEK_END);
fsize = ftell(fp);
fseek(fp,0,SEEK_SET);//reset stream position!!
return fsize;
}
char *ReadToEnd(const char *filepath){
FILE *fp;
long fsize;
char *buff;
if(NULL==(fp=fopen(filepath, "rb"))){
perror("file cannot open at ReadToEnd\n");
return NULL;
}
fsize=GetFileSize(fp);
buff=(char*)malloc(sizeof(char)*fsize+1);
fread(buff, sizeof(char), fsize, fp);
fclose(fp);
buff[fsize]='\0';
return buff;
}
char** split(const char *str, const char *delimiter, size_t *len){
char *text, *p, *first, **array;
int c;
char** ret;
*len = 0;
text=strdup(str);
if(text==NULL) return NULL;
for(c=0,p=text;NULL!=(p=strtok(p, delimiter));p=NULL, c++)//count item
if(c==0) first=p; //first token top
ret=(char**)malloc(sizeof(char*)*c+1);//+1 for NULL
if(ret==NULL){
free(text);
return NULL;
}
strcpy(text, str+(first-text));//skip until top token
array=ret;
for(p=text;NULL!=(p=strtok(p, delimiter));p=NULL){
*array++=strdup(p);
}
*array=NULL;
*len=c;
free(text);
return ret;
}
void free4split(char** sa){
char **array=sa;
if(sa!=NULL){
while(*sa)
free(*sa++);//for string
free(array); //for array
}
}
int main(){
char *text, **lines;
size_t line_count;
text=ReadToEnd("data.txt");
lines=split(text, "\r\n", &line_count);
free(text);
{ //test print
int i;
for(i=0;i<line_count;++i)
printf("%s\n", lines[i]);
}
free4split(lines);
return 0;
}

Resources