C rename() can't seem to get it to work - c

I'm trying to make a program that takes in a database of listfile names and compare it with another list. When there is a match it should rename the file with that name to the corresponding relationNumber.
At the end of the code I try to rename the file, but it doesn't let me. Is it because I'm trying to pass chars instead of const chars? And if so, how can I solve this? Before I try to rename the file I printed the strings out to see what is in them and the strings contain; "Zaalstra legitimatie.txt" and "1.17234842.txt" which is what I want. Thanks in advance.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define relationLen 10
#define true 1
#define false 0
#define resetptr NULL
typedef int bool;
char* strcasestr(char* haystack, char* needle) {
size_t i, j;
if (!needle[0])
return (char*) haystack;
for (i = 0; haystack[i]; i++) {
bool matches = true;
for (j = 0; needle[j]; j++) {
if (!haystack[i + j])
return NULL;
if (tolower((unsigned char)needle[j]) != tolower((unsigned char)haystack[i + j])) {
matches = false;
break;
}
}
if (matches)
return (char *)(haystack + i);
}
return NULL;
}
int main(void) {
char database[1024][30];
char name[30] = {0};
char newName[30] = {0};
char extension[1024][5];
char lined[256], linef[256];
char relationNumber[] = "1.1";
char newRelationNumber[relationLen] = {0};
char *ret, *number;
int i, j, c, k, len = 0;
FILE* filef = fopen("filelist.txt", "r");
for(i = 0; (c = fgetc(filef)) != EOF; i++) {
fgets(linef, sizeof(linef), filef);
strcpy(database[i], (char[2]){(char) c, '\0'});
strcat(database[i], linef);
len = strlen(database[i]);
for(j = 0, k = 5; j < 4; j++, k--) {
extension[i][j] = database[i][len-k];
}
printf("%s ", extension[i]);
printf("%s", database[i]);
}
FILE* filed = fopen("Database.txt", "r");
fgets(lined, sizeof(lined), filed);
printf("%s", lined);
number = strstr(lined, relationNumber);
for(i = 0; lined[i] != 9; i++)
newName[i] = lined[i];
newName[i] = '\0';
for(i = 0; i < relationLen; i++)
newRelationNumber[i] = number[i];
newRelationNumber[i] = '\0';
number = resetptr;
strcat(newRelationNumber, ".txt");
ret = strcasestr(database[i], newName);
printf("%s", database[0]);
printf("%s", newRelationNumber);
i = rename(database[0], newRelationNumber);
printf("\n%d", i);
return 0;
}

Related

strcmp returns __strcmp_sse2_unaligned () in a simple string search programme

I am currently fighting with a primitive search routine. It uses strcmp to compare a string given against a two dim array of strings.
GDP returns:
"__strcmp_sse2_unaligned () at ../sysdeps/x86_64/multiarch/strcmp-sse2-unaligned.S:30 30 ../sysdeps/x86_64/multiarch/strcmp-sse2-unaligned.S: No such file or directory".
Edited: Trying to move on, added command line for string input procedure. Somehow, it is mistaken.
here is my code
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
char dictionary()
{
char **strings = (char**)malloc(5*sizeof(char*));
int i = 0;
for(i = 0; i < 5; i++){
//printf("%d\n", i);
strings[i] = (char*)malloc(7*sizeof(char));
}
sprintf(strings[0], "mark");
sprintf(strings[1], "ala");
sprintf(strings[2], "wojtek");
sprintf(strings[3], "tom");
sprintf(strings[4], "john");
for(i = 0; i < 5; i++){
printf("Line #%d(length: %lu): %s\n", i, strlen(strings[i]),strings[i]);
}
for(i = 0; i < 5; i++){
free(strings[i]);
}
free(strings);
}
int cmp(char *s1, char *s2[][10]){
int i = 0;
//size_t l = strlen(s1);
for (i = 0; i < 5; i++){
if (strcmp(s1, s2[i][7*sizeof(char)]) == 0)
{
printf("OK \n");
} else {
printf("sth is wrong \n");
}
return 0;
}
}
int main(){
char BufText[255];
int n=0;
char sign;
fflush(stdin);
n = 0;
do {
sign = getchar();
BufText[n ++] = sign;
if(n >= 253) break;
} while (sign !='\n');
BufText [n] = 0;
char **dict = dictionary();
cmp(BufText, dict);
free_dictionary(dict);
return 0;
}
As said in the comments, there's a lot of flaws in your code.
First in your main, you're trying to cmp("ala", dictionary); but dictionary is an undeclared variable. I think you wanted to use the result of your dictionary() call into the cmp call. So you need to store the dictionary() result into your dictionary variable. It can't actually be done because your dictionary() func does not return anything and free the allocated dict before it can be used.
I could continue this way but here's a patched version of your code. Feel free to ask for clarifications.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
char **dictionary()
{
char **dict = (char**)malloc(sizeof(char*) * 5);
int i = 0;
for (i = 0; i < 5; i++)
dict[i] = (char*)malloc(sizeof(char) * 7);
sprintf(dict[0], "mark");
sprintf(dict[1], "ala");
sprintf(dict[2], "wojtek");
sprintf(dict[3], "tom");
sprintf(dict[4], "john");
for (i = 0; i < 5; i++)
printf("Line #%d(length: %lu): %s\n", i, strlen(dict[i]),dict[i]);
return (dict);
}
void free_dictionary(char **dict)
{
for (int i = 0; i < 5; i++)
free(dict[i]);
free(dict);
}
void cmp(char *s1, char *s2[5])
{
int i = 0;
for (i = 0; i < 5; i++)
{
if (strcmp(s1, s2[i]) == 0)
printf("OK \n");
else
printf("sth is wrong \n");
}
}
int main()
{
char **dict = dictionary();
cmp("ala", dict);
free_dictionary(dict);
return (0);
}

Functions fopen/calloc/malloc and and ways of their replacement

I want to make a simple program (but difficult for me), which will find contacts by letters (parts of the name are entered using numbers) and by numbers (parts of the number). Input - numbers, from the standard input (txt file), output - contacts that contain these numbers (letters). The contact file looks like
(name)
(number)
(name)
(…)
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#define MAX_NAME (128)
#define MAX_NUM (32)
/*
IN :
contacts.txt :
Sad Mirrow
38074025
Deniel Kovalski
78032596
Miky Trance
88055535
Martin Worried
77432651
96 [key number from standard entry]
OUT:
Deniel Kovalski
[because 96 matches in his number]
Martin Worried
[96 matches in his name Wo]
*/
typedef struct Contact {
char* name;
char* number;
} Contact;
char matchTable[10][9] = {
"0+", "1", "2abcABC", "3defDEF", "4ghiGHI",
"5jklJKL", "6mnoMNO", "7pqrsPQRS", "8tuvTUV", "9wxyWXY"
};
bool find(char c, char key){
int j = key - '0';
for (int i = 0; matchTable[j][i] != '\0'; i++){
if (c == matchTable[j][i])
return true;
}
return false;
}
bool matches(char* src, char* key){
unsigned int i,j;
for (i = 0; src[i] != '\0'; i++){
int tmp = i;
for (j = 0; key[j] != '\0'; j++){
if (find(src[tmp], key[j]))
tmp++;
else
break;
}
if (j == strlen(key))
return true;
}
return false;
}
int main(){
char key[MAX_NUM];
scanf("%s", key);
size_t arrSize = 32;
Contact* contacts = malloc(arrSize * sizeof(Contact));
int k = 0;
size_t nameSize = MAX_NAME;
size_t numSize = MAX_NUM;
char *nameBuf = malloc(MAX_NAME);
char *numBuf = malloc(MAX_NUM);
FILE* f = fopen("contacts.txt", "r");
while (fgets(nameBuf, nameSize, f)
&& fgets(numBuf, numSize, f)){
contacts[k].name = malloc(MAX_NAME);
contacts[k].number = malloc(MAX_NUM);
strcpy(contacts[k].name, nameBuf);
strcpy(contacts[k].number, numBuf);
k++;
if (k == arrSize);
arrSize <<= 1;
contacts = realloc(contacts, arrSize * sizeof(Contact));
}
for (int i = 0; i < k; i++){
bool matchesName = matches(contacts[i].name, key);
bool matchesNumber = matches(contacts[i].number, key);
if (matchesName || matchesNumber)
printf("%s\n", contacts[i].name);
}
for (int i = 0; i < k; i++){
free(contacts[i].name);
free(contacts[i].number);
}
free(contacts);
free(nameBuf);
free(numBuf);
fclose(f);
return 0;
}
At first we did as we could. Then was a time to fulfill the conditions of the task and the problem came. It needs to be done without malloc/calloc/fopen. I tried to fix everything, but I ran into a problem that the program does not work and it seems to me that I'm confused.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#define MAX_NAME (128)
#define MAX_NUM (64)
struct Folio
{
char name[1000];
char num[1000];
};
static char matchTable[10][9] = {
"0+", "1", "2abcABC", "3defDEF", "4ghiGHI",
"5jklJKL", "6mnoMNO", "7pqrsPQRS", "8tuvTUV", "9wxyWXY"
};
int find(char c, char key){
int j = key - '0';
for (int i = 0; matchTable[j][i] != '\0'; i++){
if (c == matchTable[j][i])
return 1;
}
return 0;
}
int matches(char* src, char* key){
unsigned int i,j;
for (i = 0; src[i] != '\0'; i++){
unsigned int tmp = i;
for (j = 0; key[j] != '\0'; j++){
if (find(src[tmp], key[j]))
tmp++;
else
break;
}
if (j == strlen(key))
return 1;
}
return 0;
}
int main(){
char key[MAX_NUM];
scanf("%s", key);
struct Folio contacts[42]; //Entry entries[42]
int contacts_count = 0; //entries_count = 0;
//FILE* f = fopen("seznam.txt", "r");
char name[1000];
char num[1000]; //number[1000]
while (fgets(name, MAX_NAME, stdin) != NULL && fgets(num, MAX_NUM, stdin) != NULL)
{
// copy to struct
strcpy(contacts[contacts_count].name, name);
strcpy(contacts[contacts_count].num, num);
contacts_count++;
}
for (int i = 0; i < contacts_count; i++){
int matchesName = matches(contacts[contacts_count].name, key);
int matchesNumber = matches(contacts[contacts_count].num, key);
if (matchesName || matchesNumber)
printf("%s%s\n", contacts[contacts_count].name, contacts[contacts_count].num);
}
//fclose(f);
return 0;
}
I want to ask the help of experienced programmers.
matchTable[10][9] is too small to save "7pqrsPQRS" as a string as needed in matchTable[j][i] != '\0';. Needs 10.
Suggest
//static char matchTable[10][9] = {
// "0+", "1", "2abcABC", "3defDEF", "4ghiGHI",
// "5jklJKL", "6mnoMNO", "7pqrsPQRS", "8tuvTUV", "9wxyWXY"
//};
static char *matchTable[10] = {
"0+", "1", "2abcABC", "3defDEF", "4ghiGHI",
"5jklJKL", "6mnoMNO", "7pqrsPQRS", "8tuvTUV", "9wxyWXY"
};
Perhaps other issues too.
I believe the main issue is the the search logic. Code loops over all contacts, but will attempt a match against the a non-existing contacts entry.
for (int i = 0; i < contacts_count; i++){
int matchesName = matches(contacts[contacts_count].name, key);
int matchesNumber = matches(contacts[contacts_count].num, key);
...
Should this use the i-th contacts ?
for (int i = 0; i < contacts_count; i++){
int matchesName = matches(contacts[i].name, key);
int matchesNumber = matches(contacts[i].num, key);
if (matchesName || matchesNumber)
printf("%s%s\n", contacts[i].name, contacts[contacts_count].num);
}
Or even
for (int i = 0; i < contacts_count; i++){
struct Folio con_p = &contacts[i] ;
int matchesName = matches(con_p->name, key);
int matchesNumber = matches(con_p->num, key);
if (matchesName || matchesNumber)
printf("%s%s\n", con_p->name, con_p->num);
}
Also take a look at answer from chux - Reinstate Monica

C - How to input and insert a string into an array of strings?

I want to insert string to the array until I type "ok". Why I am getting just "ok" and original array at the output?
int main(void)
{
char b[20];
char* str[10] = { "1","2" };
int i = 2;
while (1) {
gets(b);
if (strcmp(b, "ok") == 0) break;
str[i] = b;
i++;
}
for (int j = 0; j < i; j++)
printf("%s ", str[j]);
return 0;
}
You need to allocate a string on each iteration:
int main(void)
{
char* b;
char* str[10] = { "1","2" };
int i = 2;
while (1) {
b = malloc(20);
gets(b);
if (strcmp(b, "ok") == 0) break;
str[i] = b;
i++;
}
for (int j = 0; j < i; j++)
printf("%s ", str[j]);
// free allocated strings
while (i > 2)
free(str[--i]);
return 0;
}
They all point to b, which gets overwritten in each iteration.
You need to create a copy of the string when you assign it:
str[i] = strdup(b);
You also may consider using fgets instead of gets; however, you will need to remove the newline:
size_t size;
fgets(str, 20, stdin);
size = strlen(str);
if(str[size-1] == '\n')
str[size-1] = '\0';
Also, print a newline at the end of your program, so it won't interfere with the shell:
putchar('\n');
Full code:
int main(void)
{
char b[20];
char* str[10] = { "1","2" };
int i = 2;
while (1) {
size_t size;
fgets(str, 20, stdin);
size = strlen(str);
if(str[size-1] == '\n')
str[size-1] = '\0';
if (strcmp(b, "ok") == 0)
break;
str[i] = strdup(b);
i++;
}
for (int j = 0; j < i; j++)
printf("%s ", str[j]);
putchar('\n');
return 0;
}
You need to make a copy of the input string, then save a pointer to the copy of the input string in your array. Something like:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char b[20];
char *str[10] = { "1","2" };
int i = 2;
char *p;
size_t lenb;
for(i = 2 ; i < 10 ; ++i)
{
fgets(b, sizeof(b), stdin);
lenb = strlen(b);
if(lenb > 0 && *(b+lenb-1) == '\n')
{
*(b+lenb-1) = '\0'; /* overwrite the trailing \n */
lenb = strlen(b);
}
if (strcmp(b, "ok") == 0)
break;
p = malloc(lenb+1);
strcpy(p, b);
str[i] = p;
}
for (int j = 0; j < i; j++)
printf("%s\n", str[j]);
return 0;
}

C histogram of words printing problems

I have this code, what i want it to do is print the string that represents the word, and print the number of times it occurred in the file, instead it outprints something liek this: (a load of blank space) and then this number -1076720020, which i have no idea where it came from, how would i go about fixing this?
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
struct podatki {
char beseda[1000];
int frekvenca;
};
void zamenjaj(char *str1, char *str2) {
char *beseda2 = (char *)malloc((strlen(str1) + 1) * sizeof(char));
strcpy(beseda2, str1);
strcpy(str1, str2);
strcpy(str2, beseda2);
free(beseda2);
}
int posodobi(struct podatki s[], const char unit[], int count) {
int i =0;
for (i = 0; i < count; i++) {
if (strcmp(s[i].beseda, unit) == 0) {
s[i].frekvenca++;
return count;
}
}
strcpy(s[count].beseda, unit);
s[count].frekvenca++;
return (count + 1);
}
int main() {
int stBes;
scanf("%d", &stBes);
//zacetne deklaracije
struct podatki s[1000];
char string[1000], unit[2000], c;
int i = 0;
int frekvenca = 0;
int j = 0;
int count = 0;
int num = 0;
//branje
for (i = 0; i < 1000; i++) {
s[i].frekvenca = 0;
}
i = 0;
do {
fflush(stdin);
c = getchar();
string[i++] = c;
} while (c != '\n');
//pretvori v majhne crke
char *p;
for (p = string; *p != '\0'; ++p) {
*p = tolower(*p);
}
string[i - 1] = '\0';
for (i = 0; i < strlen(string); i++) {
while (i < strlen(string) && string[i] != ' ' && !ispunct(string[i])) {
unit[j++] = string[i++];
}
if (j != 0) {
unit[j] = '\0';
count = posodobi(s, unit, count);
j = 0;
}
}
int a;
for (i = 0; i < count; ++i) {
for (j = i + 1; j < count; ++j) {
if (s[i].frekvenca < s[j].frekvenca) {
a = s[i].frekvenca;
s[i].frekvenca = s[j].frekvenca;
s[j].frekvenca = a;
zamenjaj(s[i].beseda, s[j].beseda);
}
}
}
for (i = 0; i < count; i++) {
for (j = 1; j < count; j++) {
if (s[i].frekvenca == s[j].frekvenca){
if (strcmp(s[i].beseda, s[j].beseda) < 0) {
a = s[i].frekvenca;
s[i].frekvenca = s[j].frekvenca;
s[j].frekvenca = a;
zamenjaj(s[i].beseda, s[j].beseda);
}
}
}
}
//printanje
for (i = 0; i < stBes; i++) {
printf("%s\t %d\n", s[i].beseda, s[i].beseda);
if (s[i].frekvenca > 1) {
num++;
}
}
return 0;
}
The problem is that you convert the string to lower case before nul terminating it.
Here
i = 0;
do {
fflush(stdin);
c = getchar();
string[i++] = c;
} while (c != '\n');
/* Goes here <---------------------+ */
/* | */
//pretvori v majhne crke | */
char *p; /* | */
for (p = string; *p != '\0'; ++p) {/* | */
*p = tolower(*p);/* | */
} /* | */
/* | */
string[i - 1] = '\0'; /* ---------------------+ */
You should also remove the fflush(stdin) and instead use getchar() to fetch the white space characters ignored by the previous scanf(), and please use scanf() correctly and check it's returned value.

Caesar cipher printing out numbers instead of decrypted Text? in C

So I have this caesar cipher program, however when I run it it only prints out numbers instead of the decrypted text. Anyone know what I am missing? I believe there might be something wrong in the bool solved function.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "rotUtils.h"
bool solved( char decodearr[], char dictarr[][30], int size1, int size2){
char* compared;
bool result = false;
for(int j = 0; j < size2; j++){
compared = strstr( decodearr, dictarr[j]);
}
if( compared != '\0'){
result = true;
}
return result;
}
int decode( char codearr[], char dictarr[][30], int size1, int size2)
{
bool solution = false;
int key = -50;
char decodearr[10000];
while(solution == false && key < 51)
{
for( int i = 0; i < size1; i++)
{
if(!isspace(codearr[i]))
{
decodearr[i] = rotate(codearr[i], key);
}
else
decodearr[i] = codearr[i];
}
solution = solved( decodearr, dictarr, size1, size2);
if( solution == false)
{
key++;
}
}
for( int j = 0; j < size1; j++)
{
codearr[j] = decodearr[j];
}
return key;
}
int main( int argc, char* argv[])
{
char* file = argv[1];
char* dictionary = argv[2];
char code[10000];
char dict[30000][30];
FILE* codeFile;
codeFile = fopen(file, "r");
int i = 0;
int j = 0;
int key;
FILE* dictFile;
dictFile = fopen(dictionary, "r");
while(!feof(codeFile))
{
code[i] = fgetc(codeFile);
i++;
}
code[ i + 1] = '\0';
fclose(codeFile);
while(!feof(dictFile))
{
fscanf(dictFile, "%s", dict[j]);
j++;
}
key = decode(code, dict, i, j);
fclose(dictFile);
for(int k = 0; k < i; k++)
{
printf("%d", code[k]);
}
printf( "\nThe key is: %d\n", key);
return 0;
}
printf("%d", code[k]); means "print out the decimal digits that represent the integer code[k]".
If you want "print out the character that represents the integer code[k], then you'd want the %c format specifier instead: printf("%c", code[k]);
You only ever print numbers
printf("%d", code[k]);
perhaps try
printf("%c", code[k]);
which prints the character that number represents.
Just use "%c" instead of "%d" in your code when you want to print code[k].
Good luck!

Resources