My C program just freezes right after the "zeroed" string printed to the terminal. I can't find out why...
int formattedMsgLen = strlen(msg)+strlen(from)-strlen(MSG_PRFX_ALL) + 1;
printf("formattedMsgLen = %d\n",formattedMsgLen);
char * formattedMsg = (char*)malloc(formattedMsgLen) ;
if (NULL == formattedMsg) {
perror("malloc:");
sem_post(&writeSem);
NAMES_MUTEX_UNLOCK;
exit(EXIT_FAILURE);
}
printf("cont. building msg\n");
//memset(formattedMsg, 0, formattedMsgLen);
printf("zeroed\n");
memcpy(formattedMsg, MSG_PRFX_ALL, strlen(MSG_PRFX_ALL));
printf("msg to all: %s",formattedMsg);
EDIT:
#define MSG_PRFX_ALL ("All")
Include a newline character in your last printf statement.
printf("msg to all: %s\n",formattedMsg);
This will clear the buffer.
strlen(MSG_PRFX_ALL)=3 and memcpy just copied only 3 letters without \0
add before printf
formattedMsg[strlen(MSG_PRFX_ALL)]='\0'
Try adding this line after the last printf:
fflush(stdout);
Replace
memcpy(formattedMsg, MSG_PRFX_ALL, strlen(MSG_PRFX_ALL));
with
strcpy(formattedMsg, MSG_PRFX_ALL);
Related
I'm trying to get each line in a loop for a wchar_t string using wcstok(), that string is supposed to contain at least two lines, the latest 'wcstok(0, L"\n")' is getting always null result and I'm getting the value of i using printf as 1 only instead of 2 or higher, but the problem got solved when doing #if 0 instead of #if 1.
this is the code below:
wchar_t* w;
wchar_t* line;
int j;
wchar_t**** lines;
int** linescount;
......
int i=0;
#if 1 //problem get solved when changing to #if 0
line = wcstok(w, L"\n");
do{
((*linescount)[j])++;
}while(line=wcstok(0, L"\n"));
(*lines)[annex] = calloc(sizeof(wchar_t**), (*linescount)[j]);
#endif
line = wcstok(w, L"\n");
do{
#if 1 //problem get solved when changing to #if 0
(*lines)[j][i] = calloc(sizeof(wchar_t*), wcslen(line)+1);
wcscpy((*lines)[j][i], line);
#endif
i++;
}while(line=wcstok(0, L"\n"));
printf("i = %d\n", i); /*prints the i value to check if the latest line=wcstok(0, L"\n") worked correctly or not*/
so what's supposed the cause of this problem? and how can I solve it? please help.
The wcstok modifies the string passed in as argument so once you have run your loop to count lines the buffer is basically kaputt.
It seems like overkill to use wcstok to count lines when you easily could just loop through the buffer counting number of \n.
I have an array of structs and they get saved into a file. Currently there are two lines in the file:
a a 1
b b 2
I am trying to read in the file and have the data saved to the struct:
typedef struct book{
char number[11];//10 numbers
char first[21]; //20 char first/last name
char last[21];
} info;
info info1[500]
into num = 0;
pRead = fopen("phone_book.dat", "r");
if ( pRead == NULL ){
printf("\nFile cannot be opened\n");
}
else{
while ( !feof(pRead) ) {
fscanf(pRead, "%s%s%s", info1[num].first, info1[num].last, info1[num].number);
printf{"%s%s%s",info1[num].first, info1[num].last, info1[num].number); //this prints statement works fine
num++;
}
}
//if I add a print statement after all that I get windows directory and junk code.
This makes me think that the items are not being saved into the struct. Any help would be great. Thanks!
EDIT: Okay so it does save it fine but when I pass it to my function it gives me garbage code.
When I call it:
sho(num, book);
My show function:
void sho (int nume, info* info2){
printf("\n\n\nfirst after passed= %s\n\n\n", info2[0].first); //i put 0 to see the first entry
}
I think you meant int num = 0;, instead of into.
printf{... is a syntax error, printf(... instead.
Check the result of fscanf, if it isn't 3 it hasn't read all 3 strings.
Don't use (f)scanf to read strings, at least not without specifying the maximum length:
fscanf(pRead, "%10s%20s%20s", ...);
But, better yet, use fgets instead:
fgets(info1[num].first, sizeof info1[num].first, pRead);
fgets(info1[num].last, sizeof info1[num].last, pRead);
fgets(info1[num].number, sizeof info1[num].number, pRead);
(and check the result of fgets, of course)
Make sure num doesn't go higher than 499, or you'll overflow info:
while(num < 500 && !feof(pRead)){.
1.-For better error handling, recommend using fgets(), using widths in your sscanf(), validating sscanf() results.
2.-OP usage of feof(pRead) is easy to misuse - suggest fgets().
char buffer[sizeof(info)*2];
while ((n < 500) && (fgets(buffer, sizeof buffer, pRead) != NULL)) {
char sentinel; // look for extra trailing non-whitespace.
if (sscanf(buffer, "%20s%20s%10s %c", info1[num].first,
info1[num].last, info1[num].number, &sentinel) != 3) {
// Handle_Error
printf("Error <%s>\n",buffer);
continue;
}
printf("%s %s %s\n", info1[num].first, info1[num].last, info1[num].number);
num++;
}
BTW: using %s does not work well should a space exists within a first name or within a last name.
This is code:
char* inputString(){
int n = 5;
int size = n;
char* const_str = (char*)malloc((n+1)*sizeof(char));
char* substring = (char*)malloc((n+n)*sizeof(char)); /*here*/
char*p;
while((fgets(const_str,n,stdin)!=NULL)&&(strchr(const_str,'\n')==NULL)){
strcat(substring,const_str);
size += n;
substring = (char*)realloc(substring,size*sizeof(char)); /*here*/
}
strcat(substring,const_str);
size += n;
substring = (char*)realloc(substring,size*sizeof(char)); /*here*/
/*
printf("<%s> is \n",const_str);
printf("%s is \n",substring);
printf("%d is \n",size);
*/
if ((p=strchr(substring,'\n'))!=NULL){
p[0]='\0';
}
if(feof(stdin)){
changeToFull();
}
return substring;
}
and it will not be work on valgrind.
I guess, that i have memory leak here, but, i can't see any good solution to rewrite this function for valgrind.
Please, help!
I haven't tried it, but I found this on a question on SO:
--input-fd=<number> [default: 0, stdin]
Specify the file descriptor to use for reading input from the
user. This is used whenever valgrind needs to prompt the user
for a decision.
Original question here: making valgrind able to read user input when c++ needs it
EDIT:
So for your case, you may try:
mkfifo /tmp/abcd
exec 3</tmp/abcd
valgrind_command...... --input-fd=3
& in another terminal, use
cat > /tmp/abcd
I am trying to make simple encryption algorithm .My aim is to translate abc (it can be any word) to 123. Then apply some functions then again translate to text, Here is my algorithm .I have problem about filing.I create unencrypted.txt which is written inside "hello world" then debug program it s creating encrypted.txt but just written w o r l d.why it s not writing hello world.always takes last word and with spaces "w o r l d",Can you help me?
Edit
https://www.dropbox.com/s/i3afkm439iv3d0v/last%20form.txt this is the last form i added multply 2 and mod 27 for encryption.it works better.but still problem.there is "hello world" in txt file.its encryption
pjxxcpjxxcpjxxcpjxxcscixhpjxxcqscixhqpjxxc scixh
but it must be pjxxc scixh
#include <cstdlib>
#include <iostream>
#include<stdio.h>
#include<string.h>
#include <conio.h>
int main()
{
int g,p,sak,v,r,t,z,o,c,l,i,j,k,*D;
char alfabe[27]={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','\0'};
FILE *fp1;
FILE *mat;
char word[20];
fp1 = fopen("unencrypted.txt","r");
do {
g = fscanf(fp1,"%s",word); /* dosyadan bir kelime oku... */
if (g != EOF) {
mat=fopen("encrypted.txt","w") ;
c=strlen(word);
printf("has %d letters ", c);
D = (int *) malloc( sizeof(int)*c );
for(i=0;i<c;i++) {
for(j=0;j<26;j++) {
if(word[i]==alfabe[j]) {
D[i]=(j+1);
break;
}
}
}
printf("\nlast form before translation ");
for(l=0;l<c;l++) {
printf("%d",D[l]); /*it s just for control */
}
for(z=0;z<c;z++){
o=D[z];
word[z]=alfabe[o-1] ; }
printf("\nnew form of word: ");
for(k=0;k<c;k++) {
fprintf(mat," %c",word[k]);
}
fclose(mat);
}
} while (g != EOF);
fclose(fp1); }
why it s not writing hello world?
You open the file everytime in the do-while loop:
mat=fopen("encrypted.txt","w") ;
So everytime the contents are overwritten. As a result, you'll only have the last word written into it. Hence, "hello" disappears.
but just written w o r l d
Because, you use white-space in fprintf:
fprintf(mat," %c",word[k]);
To fix it:
Open the file only once.
Remove the the white-space from the fprintf.
fprintf(mat,"%c",word[k]);
You are opening the file for writing inside the loop:
do {
...
mat=fopen("encrypted.txt","w") ;
...
// writing to file
...
} while(g != EOF);
as a result each iteration of the loop will wipe off the old file contents.
It is doing so because you are open file in "w" write mode, so it clears the previous content. Try opening it in "a+" mode.
you are using fscanf(...,"%s",...);
Now that is wrong for a simple reason, no matter how big your buffer is, the input can always be one byte longer.
Since you are processing the input one character at a time, you should read one character at a time.
crazy loop
I'm pretty sure you meant to write D[i] = word[i]-'a';, plus you should test if the character is small alphabetic character by using islower().
o=D[z]; word[z] = alfabe[o-1];
Now this doesn't make much sense. What if the character is a? You would be accessing alfabe[-1].
What I wont to do is to create a terminal menu that takes various types of arguments and place it in a array param. Under is the code: Here is some trouble that I have and cant find a good solution for.
if i just type 'list' I will get Not a valid command, I have to type “list “ (list and space).
Menu choice new should be like this: new “My name is hello”. param[0] = new and param[1] = My name is hello , (sow I can create a message with spaces).
How can I accomplish this?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
int menu()
{
printf(">");
char line[LINE_MAX];
int i = 0;
char *param[4];
while(fgets(line, LINE_MAX, stdin) != NULL) {
param[i++] = strtok(line, " \n");
if(param[0] != NULL) {
char *argument;
while((argument = strtok(NULL, "\n")) != NULL) {
param[i++] = argument;
}
}
if(strcmp(param[0], "new") == 0) {
//new(param[1]);
menu();
} else if(strcmp(param[0], "list") == 0) {
//list();
menu();
} else {
printf("Not a valid command.\n\n");
menu();
}
}
return 0;
}
You're delimiting on " ".
fgets reads the ENTER.
So, when you type "listENTER" and tokenise at spaces you get one token, namely "listENTER". Later you compare with "list" and, of course, it doesn't match.
Try
strtok(line, " \n"); /* maybe include tabs too? */
PS. Why are you calling menu recursively? You already have a while in the function ...
Your problem is param[i++] = strtok(line, " "); will only split on space, not on \n (newline). Try adding this to your array of delimeters.
Oh, and congratulations for some decent looking code that's clean and well formatted. A pleasant change.
I'm not sure if this causes your problem but these lines
/*new(param[1]);
/*list();
Start a comment that is never terminated.
If you want one line comments you can use:
// comment
(atleast in C++ and from C99 on)
But comments starting with /*must be ended with a */and not nested:
/* comment */
/* also multi line
allowed */
Since you start a comment in a comment your compiler should have emmited a warning, actually this shouldn't compile at all.
The reason you need to type "list " is that your first strtok tokenizes until a space character, so you need to enter one in this case. Try allowing both '\n' and space as separators, i.e. replace the second parameter of strtok with " \n".
As for quotes, you need to re-combine parameters starting from the one beginning with a quote to the one ending with one by replacing the characters in between them with spaces. Or do away with strtok and parse by manually iterating through the characters in line.