C 2d strings issue - c

#include<stdio.h>
#include<string.h>
void fill_A (char A[][10],int *pos1,int *pos2)
{
int j,k,l;
while (j=0)
{
k=0;
do{
printf("keep entering and terminate by end");
gets(A[k]); k++;}while(strcmp(A[k-1],"end")!=0);
*pos2=k-1;
for(l=0;l<k;l++)
{
if (strcmp(A[l],"middle")==0)
{
j=1; *pos1=l; break; }
}
}
}
void fill_B(char A[][10],char B[][10],int pos1)
{
int j,k;
for(j=0;j<pos1;j++)
{
strcpy(B[j],A[j]);
}
}
void fill_C(char A[][10],char C[][10],int pos1,int pos2)
{
int j;
for (j=pos1;j<pos2;j++)
{
strcpy(C[j],A[j]);
}
}
void print (char A[][10],int lim)
{
int j;
for (j=0;j<lim;j++)
{
puts(A[j]);
}
}
void main()
{
char A[100][10],B[100][10],C[100][10];
int pos1,pos2;
fill_A(A,&pos1,&pos2);
fill_B(A,B,pos1);
fill_C(A,C,pos1,pos2);
print (B,pos1);
print(C,pos2-pos1);
}
I am trying to:
1)Keep entering strings until terminated by user (entering end)
2) the list of strings should have a string "middle"
3) words before middle put in 2d string B
4) words between middle and end put in 2d string C.
Run: just a screen that I cannot type into.
Can you find the problem? Thank you!

Related

Unable to list out stack

I am trying to do a push, pop and list function into a stack. It should first push 4 strings(I write them as array because %s cannot run properly), and then pop 3 strings out, and list the last string. However, the code can't run properly. Can somebody helps me?
This is the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include<conio.h>
#define MAX 4
int point = -1;
char item[MAX][20];
void push(char item[point])
{
point++;
};
void pop(char item[point])
{
point--;
};
void list()
{
if (point > -1) {
for (int i = 0; i <= point; i++) {
printf("%c\n", item[point-i]);
}
}
};
int main()
{
//AB01
char arrA[4] = {'A','B','0','1'};
for(int i=0;i<4;i++)
{
printf("%c",arrA[i]);
}
point++;
printf("\n");
push (arrA[4]);
//AB02
char arrB[4] = {'A','B','0','2'};
for(int i=0;i<4;i++)
{
printf("%c",arrB[i]);
}
point++;
push (arrB[4]);
printf("\n");
//AB03
char arrC[4] = {'A','B','0','3'};
for(int i=0;i<4;i++)
{
printf("%c",arrC[i]);
}
point++;
push (arrC[4]);
printf("\n");
//AB04
char arrD[4] = {'A','B','0','4'};
for(int i=0;i<4;i++)
{
printf("%c",arrD[i]);
}
point++;
push (arrD[4]);
printf("\n");
//Delete 3 strings
pop(arrA[point]);
pop(arrB[point]);
pop(arrC[point]);
list();
return 0;
}
It seems that the list cannot run properly. Because I'd used arrays to show the strings, and it makes me unable to list properly(because I used an array again in the list(), and then it becomes 2 array). What should I do if I want to let my strings(characters in array) being list?

How to fix the error "comparison between pointer & integer"?

I have been trying to compare a structure variable and a string variable. But I am getting this error.
#include<stdio.h>
#include<string.h>
int main()
{
struct details {
char number[20];
} det[10];
int inp, i=0;
char aad;
int b;
puts("Give The Number To Display The Pass Status");
scanf("%s", &aad);
for(b=0;b<i;b++)
{
if(det[i].number==aad)
{
printf("Hello");
}
}
return 0;
}
Pls try to fix my error
after you look in the comments this will be the answer
#include<stdio.h>
#include<string.h>
#define SIZE 20 // add size for aad
int main()
{
struct details {
char number[20];
} det[10];
int inp, i = 0;
char aad[SIZE]; // must be array (can be with pointer, use malloc)
int b;
puts("Give The Number To Display The Pass Status");
scanf("%s", &aad);
for (b = 0; b < i; b++)
{
if (strcmp(det[b].number, aad) == 0) // strcmp to compare strings
{
printf("Hello");
}
}
return 0;
}

Structure printf stops the program from working

I created the following code, it compiles but it doesen't run properly. It shows some imput witch is correct, but after that, instead of printing according to the line printf(prod[0].dr[0]); it enters an "not responding" state. If you instead write printf(prod[0].dr); it works perfectly. I need to be able to print each character individualy (so I need something like printf(prod[0].dr[0]); that works)
If the question is to broad, please comment and I will try to specify every detail.
Thanks!
#include <stdio.h>
FILE *f, *g;
struct productie
{
char st, dr[20];
int realizabil;
}prod[30];
int citire(FILE *f){
char sir[100];
int i=0,j;
while(!feof(f))
{
fgets(sir,100,f);
prod[i].st=sir[0];
for(j=3;j<strlen(sir);j++)
prod[i].dr[j-3]=sir[j];
i++;
}
return i;
}
int exista(char sir[],char c)
{
int i;
for(i=0;i<strlen(sir);i++)
{
if(c==sir[i])
return 1;
}
return 0;
}
void neterminale(struct productie p[],int n, char N[])
{
int k=0;
int i,j;
for(i=0;i<n;i++)
{
if(isupper(p[i].st) && !exista(N,p[i].st))
N[k++]=p[i].st;
for(j=0;j<strlen(p[i].dr);j++)
if(isupper(p[i].dr[j]) && !exista(N,p[i].dr[j]))
N[k++]=p[i].dr[j];
}
N[k]='\0';
}
void terminale(struct productie p[],int n, char T[],char N[])
{
int k=0;
int i,j;
for(i=0;i<n;i++)
{
if(!exista(N,p[i].st) && !exista(T,p[i].st)&& p[i].st!='$')
T[k++]=p[i].st;
for(j=0;j<strlen(p[i].dr);j++)
if(!exista(N,p[i].dr[j]) && !exista(T,p[i].dr[j]) && p[i].dr[j]!='$')
T[k++] = p[i].dr[j];
}
T[k]='\0';
}
void afisare(FILE *g,int n){
int i;
for(i=0;i<n;i++)
fprintf(g,"%c -> %s",prod[i].st, prod[i].dr);
}
int main(){
char N[30];
char T[30];
int i,j,n;
f=fopen("in.txt","r");
n=citire(f);
neterminale(prod,n,N);
printf("\nNeterminalele sunt:{");
for(i=0;i<strlen(N);i++)
printf("%c ",N[i]);
printf("}");
terminale(prod,n,T,N);
printf("\nTerminalele sunt:{");
for(i=0;i<strlen(T);i++)
{
printf(" %c ",T[i]);
}
printf("}");
printf(prod[0].dr[0]); //AT THIS LINE IS THE PROBLEM
g=fopen("out.txt","w");
afisare(g,n);
fclose(f);
fclose(g);
return 0;
}
The in.txt :
S->aS
S->a
S->$
S->AB
A->b
B->c
If you want to print a string directly, you need to provide a pointer to the first character, not the first character itself:
printf(&(prod[0].dr[0]));
or
printf(prod[0].dr);
But you can't limit this to a single char (there is no nprintf function).

Username and Password in C

so basically I want to create a program that asks for an username and a password in order to enter the actual program. I tried doing something like that but when I type the first username and password it doesn't let me go through. On the other hand when I type the second username and password it does work. Can someone explain me why?
#include<stdio.h>
#include<string.h>
#define MAX 100
#define LEN 40
int names(char listName[][LEN]);
void pass(char listPass[][LEN]);
int main()
{
char name[LEN];
char password[LEN];
char listName[MAX][LEN];
char listPass[MAX][LEN];
int i;
names(listName);
pass(listPass);
printf("Enter username: ");
scanf("%s", name);
printf("Enter password: ");
scanf("%s", password);
for(i = 0; i< 2; i++)
{
if (strcmp(listName[i], name) == 0 && strcmp(listPass[i], password) == 0)
{
printf("Access granted\n");
break;
}
else
{
printf("Access denied\n");
break;
}
}
getch();
}
int names(char listName[][LEN])
{
int i;
strcpy(listName[i], "Vince");
strcpy(listName[i], "Jeremy");
}
void pass(char listPass[][LEN])
{
int i;
strcpy(listPass[i], "aBc2xyz8");
strcpy(listPass[i], "fa7saC12");
}
Compile with warnings enabled and you'd see that the variable i is used uninitialized here:
int names(char listName[][LEN])
{
int i;
strcpy(listName[i], "Vince");
strcpy(listName[i], "Jeremy");
}
void pass(char listPass[][LEN])
{
int i;
strcpy(listPass[i], "aBc2xyz8");
strcpy(listPass[i], "fa7saC12");
}
What you have now is undefined behaviour, i.e. anything can happen. More likely you'd just get a random crash.
You meant strcpy(listName[0], "Vince");, strcpy(listName[1], "Jeremy");
However, what you'd really want to do is to define these variables *out of main, and initialize them there. Also, allow for varying length passwords and usernames by using an array of pointers to char. For example:
char *listName[MAX] = { "Vince", "Jeremy" };
char *listPass[MAX] = { "aBc2xyz8", "fa7saC12" };
int main(void) { ...
Or even better, use a structure for user data:
struct user_data {
char *username, *password;
};
struct user_data users[MAX] = {
{ "Vince", "aBc2xyz8" },
{ "Jeremy", "fa7saC12" }
};
In names() and pass() you use i uninitialized, both strcpy operations are going to copy to the same array index.
Following code is not what you intended:
int names(char listName[][LEN])
{
int i;
strcpy(listName[i], "Vince");
strcpy(listName[i], "Jeremy");
}
void pass(char listPass[][LEN])
{
int i;
strcpy(listPass[i], "aBc2xyz8");
strcpy(listPass[i], "fa7saC12");
}
You should initialize i and increment it between the statements, or simply use:
int names(char listName[][LEN])
{
strcpy(listName[0], "Vince");
strcpy(listName[1], "Jeremy");
}
void pass(char listPass[][LEN])
{
strcpy(listPass[0], "aBc2xyz8");
strcpy(listPass[1], "fa7saC12");
}

Segmentation fault when copying string to

Hit there!
Below is a little program I made today. It takes a table of strings, reverses all strings without reversing table, then sorts those reversed string, then reverses them back, and at last prints whole table.
I was trying really long to figure out why can't I copy 'slowo' string into place in table pointed in strcmp, but with no success. I would be happy if someone would find a way to fix Segmentation Fault in this case, but I really want to leave the method as it is below.
Thanks for your help! :)
EDIT By using debugger I determined that Segmentation Fault appears in strcpy, if that wasn't clear...
#include <stdio.h>
#include <string.h>
const int ROZMIAR=4;
char* nieposortowane[]={"basia", "zosia", "ala", "genowefa"};
int porownaj(char* a, char* b)
{
return strcmp(a,b);
}
void sortowanie(char** tablica, int N)
{
int zamienione, i;
char tmp;
do
{
zamienione=0;
for(i=0;i<N-1;i++)
if(porownaj(nieposortowane[i], nieposortowane[i+1])>0)
{
tmp=**(tablica+i);
**(tablica+i)=**(tablica+(i+1));
**(tablica+(i+1))=tmp;
zamienione=1;
}
}
while(zamienione);
}
void wypisz(char** tablica, int N)
{
int i=0;
for(i=0;i<N;i++)
printf("%s\n", *(tablica+i));
}
void odwr(char** tablica, int N)
{
int i, ln, c;
int start, koniec;
char temp;
for(i=0;i<N;i++)
{
ln = strlen(tablica[i]);
char slowo[ln];
strcpy(slowo,*(tablica+i));
start=0;
koniec=ln-1;
for(c=0;c<(ln/2);c++)
{
temp =slowo[start];
slowo[start]=slowo[koniec];
slowo[koniec]=temp;
start++;
koniec--;
}
strcpy(*(tablica+i), slowo);
}
}
int main()
{
printf("Przed sortowaniem: \n");
wypisz(nieposortowane, ROZMIAR);
odwr(nieposortowane, ROZMIAR);
sortowanie(nieposortowane, ROZMIAR);
odwr(nieposortowane, ROZMIAR);
printf("Po sortowaniu babelkowym: \n");
wypisz(nieposortowane, ROZMIAR);
return 0;
}
When allocating slowo, you should add 1 to the result of strlen when calculating the size to allocate. This is to accomodate the terminating null character, which is not included in a string's length (returned by strlen), but must be included in its total allocated size.
AFAICS, you are trying to modify the strings in:
char* nieposortowane[]={"basia", "zosia", "ala", "genowefa"};
Those are string literals stored in read-only memory; any attempt to modify them (for example, by reversing them) will fail.
I reproduced the crash with your original code. This revision of the code doesn't crash; it goes into an infinite loop in your sort code instead. I've not debugged that part of your code.
#include <stdio.h>
#include <string.h>
const int ROZMIAR=4;
char basia[] = "basia";
char zosia[] = "zosia";
char ala[] = "ala";
char genowefa[] = "genowefa";
char* nieposortowane[]={basia, zosia, ala, genowefa};
int porownaj(char* a, char* b)
{
return strcmp(a,b);
}
void sortowanie(char** tablica, int N)
{
int zamienione, i;
char tmp;
do
{
zamienione=0;
for(i=0;i<N-1;i++)
if(porownaj(nieposortowane[i], nieposortowane[i+1])>0)
{
tmp=**(tablica+i);
**(tablica+i)=**(tablica+(i+1));
**(tablica+(i+1))=tmp;
zamienione=1;
}
}
while(zamienione);
}
void wypisz(char** tablica, int N)
{
int i=0;
for(i=0;i<N;i++)
printf("%s\n", *(tablica+i));
}
void odwr(char** tablica, int N)
{
int i, ln, c;
int start, koniec;
char temp;
for(i=0;i<N;i++)
{
ln = strlen(tablica[i]);
char slowo[ln];
strcpy(slowo,*(tablica+i));
start=0;
koniec=ln-1;
for(c=0;c<(ln/2);c++)
{
temp =slowo[start];
slowo[start]=slowo[koniec];
slowo[koniec]=temp;
start++;
koniec--;
}
strcpy(*(tablica+i), slowo);
}
}
int main()
{
printf("Przed sortowaniem: \n");
wypisz(nieposortowane, ROZMIAR);
odwr(nieposortowane, ROZMIAR);
wypisz(nieposortowane, ROZMIAR);
sortowanie(nieposortowane, ROZMIAR);
wypisz(nieposortowane, ROZMIAR);
odwr(nieposortowane, ROZMIAR);
wypisz(nieposortowane, ROZMIAR);
printf("Po sortowaniu babelkowym: \n");
wypisz(nieposortowane, ROZMIAR);
return 0;
}
Sample output:
Przed sortowaniem:
basia
zosia
ala
genowefa
aisab
aisoz
ala
afewoneg
I had to interrupt after that, but you can see that the strings are reversed successfully.
You'll need to sort out a more general solution; naming the individual arrays as I did is easy for a small fixed set, but not generally. One possibility would be to use strdup() to duplicate each string into allocated space:
enum { SIZE_NPSW = sizeof(nieposortowane) / sizeof(nieposortowane[0] };
for (i = 0; i < SIZE_NPSW; i++)
nieposortowane[i] = strdup(nieposortowane[i]);

Resources