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).
Related
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;
}
I've looked around but can't seem to find how to do this. I want the value of empty lines from test2(int *f) to be passed to test1() and be printed on the screen.
Variant 1 of code:
#include <stdio.h>
#include <string.h>
void test1();
void test2(int *f);
void test1(){
int a;
test2(&a);
printf("%d \n", a);
}
void test2(int *f){
char str[80];
int lines, i, emptylines=0;
*f=emptylines;
printf("Type a program here. Ctrl+Z and enter to stop.\n");
fflush(stdin);
while(gets(str)!=NULL && strcmp(str, "qq")) {
for(i=0; i<strlen(str); i++){
if(str[i]!='\n') lines=1;
}
if(!lines) emptylines++;
lines=0;
}
}
int main() {
test1();
return 0;
}
Variant 2 of code:
#include <stdio.h>
#include <string.h>
void test1();
void test2(int *f);
void test1(){
int a;
test2(&a);
printf("%d \n", a);
}
void test2(int *f){
char str[80], *p;
int lines, emptylines=0;
*f=emptylines;
printf("Type a program here. Ctrl+Z and enter to stop.\n");
fflush(stdin);
while(gets(str)!=NULL && strcmp(str, "qq")) {
p=str;
lines=0;
while(*p!='\0') {
if(*p!=' ') {
lines=1;
}
p++;
}
if(lines==0){
emptylines++;
lines=0;
}
}
}
int main() {
test1();
return 0;
}
You are putting *f=emptylines in the beginning of the function void test2(int *f); Then you calculate emptylines but this will not affect the value pointed-to by f.
You need to move that assignment *f=emptylines to the end of the function, just before returning and after having calculated emptylines
void test2(int *f){
// stuff to calculate emptylines
....
*f=emptylines; // at the end
}
When you write
*f = emptylines;
you are copying the value of emptylines into the space pointed to by f. Then when you update emptylines later, the value pointed to by f doesn't change because you made a copy.
Rather than using another variable emptylines just use the parameter f directly to compute the value. Though I'd give it a more descriptive value than f, something like numEmptyLines.
#include <stdio.h>
#include <string.h>
void test1();
void test2(int *numEmptyLines);
void test1(){
int a;
test2(&a);
printf("%d \n", a);
}
void test2(int *numEmptyLines){
char str[80];
int lines, i;
*numEmptyLines = 0;
printf("Type a program here. Ctrl+Z and enter to stop.\n");
fflush(stdin);
while(gets(str)!=NULL && strcmp(str, "qq")) {
for(i=0; i<strlen(str); i++){
if(str[i]!='\n') lines=1;
}
if(!lines) (*numEmptyLines)++;
lines=0;
}
}
int main() {
test1();
return 0;
}
the code is:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 20
typedef struct word{
char word[20];
int occurrance;
} word;
int array_word_creator(word *array, FILE *fp);
void initialize(word array[], int max);
void comparator(word array[], int max, FILE *fp);
void printer(word array[], int max);
int main(int argc, char *argv[])
{
FILE *f_sent, *f_words;
word *array;
int arr_lenght=0;
if(argc!=3)
{
printf("Wrong argument number, please use NAME FILE1 FILE2;\n");
exit(EXIT_FAILURE);
}
if((f_sent=fopen(argv[1], "r"))==NULL||(f_words=fopen(argv[1], "r"))==NULL)
{
printf("Can't find or open the files, please check if the name is correct\n");
exit(EXIT_FAILURE);
}
arr_lenght=array_word_creator(array, f_words);
comparator(array, arr_lenght ,f_sent);
printer(array, arr_lenght);
return 0;
}
int array_word_creator(word *array, FILE *fp)
{
int n,i=0;
fscanf(fp,"%d",&n);
*array= malloc(n*sizeof(word));
while(fscanf(fp,"%s", array[i].word)!=EOF)
{
i++;
}
initialize(array,n);
return n;
}
void initialize(word array[], int max)
{
int i;
for(i=0;i<max;i++)
{
array[i].occurrance=0;
}
}
void comparator(word array[], int max, FILE *fp)
{
char word[MAX];
int i;
while(fscanf(fp,"%s", word)!=EOF)
{
for(i=0;i<max;i++)
{
if(strcmp(word, array[i].word)==0)
{
array[i].occurrance++;
}
}
}
}
void printer(word array[], int max)
{
int i;
for(i=0;i<max;i++)
{
if(array[i].occurrance>0)
{
printf("The word '%s' occurs %d times\n", array[i].word, array[i].occurrance);
}
}
}
And the compiler says me:
C:\Users\Matteo\Google Drive\Programming\C\lab3\es1\main.c|47|error: incompatible types when assigning to type 'word' from type 'void *'|
I just studied memory allocation so i'm having some trouble with it, especially with structures. If possible, plase link me also some good docs about this subject.
thank you!
In main word *array is a pointer to a structure of type word.
You then pass array, which does not point to anything, to the function array_word_creator.
You then try to assign the pointer returned by malloc to where array is pointing, but it doesn't point anywhere yet, and even if it did, it would be pointing to a word (since it is a word *), so it can't store a pointer, hence the compiler error.
If you want to set the array pointer in main to the result of malloc, you have to pass a pointer to the pointer. int array_word_creator(word **array, FILE *fp), then you would call it by doing array_word_creator(&array, .... ), the your *array = malloc will work.
You want this:
...
arr_lenght = array_word_creator(&array, f_words);
...
int array_word_creator(word **array, FILE *fp)
{
int n, i = 0;
fscanf(fp, "%d", &n);
*array = malloc(n * sizeof(word));
while (fscanf(fp, "%19s", (*array)[i].word) != EOF)
{
i++;
}
initialize(*array, n);
return n;
}
#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!
Here is my code:
#define MAX_SET_LENGTH 255
typedef struct{
char name;
char *elemetns;
}Set;
void createSet();
int getString();
void filter(char raw[],int *length);
void menu();
void del_duplicate(char *s,int n);
void displyAllSets();
Set sets[26];
int setCount=0;
int main(){
menu();
}
void menu(){
int input;
do{
printf("\n1.Create Set.\n");
printf("2.display all Sets.\n");
printf("0.Exit.\n");
scanf("%d",&input);
switch(input){
case 0:
break;
case 1:
createSet();
break;
case 2:
displyAllSets();
break;
default:
printf("Error input,please input again\n");
}
}while (input!=0);
}
void displyAllSets(){
int i;
for(i=0; i<setCount; i++) {
printf("\n%c->{%s}\n",sets[i].name,sets[i].elemetns);
}
}
void createSet(){
if(setCount<26){
printf("Please input the set's elements:\n");
char elements[MAX_SET_LENGTH];
int s_length = getString(elements,MAX_SET_LENGTH);
filter(elements,&s_length);
del_duplicate(elements,s_length);
if(s_length > 0){
elements[s_length]='\0';
Set set;
set.elemetns = elements;
set.name = 'a'+ setCount;
sets[setCount++]=set;
displyAllSets();
}else{
printf("No illegal input!\n");
}
}else{
printf("It's limit to 26");
}
}
int getString(char s[],int max_length){
char c;
int i=0;
getchar();
while((c=getchar())!='\n')
s[i++]=c;
return (i>=max_length ? max_length : i);
}
void filter(char raw[],int *length){
char string[*length];
int i=0,j=0;
int deletedCount=0;
for(;i<*length;i++){
string[i]=raw[i];
}
for(i=0;i<*length;i++){
if(string[i]>='A' && string[i]<='Z'){
raw[j++]=string[i];
}else{
deletedCount++;
}
}
*length-=deletedCount;
raw[j]='\0';
}
void del_duplicate(char raw[],int length){
int i=0,j;
for(;i<length && length>0;i++){
for(j=i+1;j<length;){
if(raw[i]==raw[j]){
int delFrom=j;
while(delFrom<length){
raw[delFrom]=raw[delFrom+1];
delFrom++;
}
j=i+1;
length--;
}else{
j++;
}
}
}
}
Everything looks good when calling createSet();
but, after calling printf("\n1.Create Set.\n") in do-while block, the array sets has been modified. Can anyone help?
after pressing F6
Can you see that left bottom window, sets[0].elements gets changed, what's happening?
You are storing the address of a local variable on this line:
set.elemetns = elements;
That is undefined behaviour. Don't do it!
If you want to copy the string, do one of the following:
Change the structure to store a char array and use strncpy to copy the string; or
Duplicate the string (and remember to free it later): set.elemetns = strdup(elements);
In a completely separate issue, you have implemented a function getString that seems to do roughly what fgets does. You should use fgets instead.