So I'm passing an string into this function, where the length of the array is at a default of 50.
I input the string using this
void inputDNA(char *dnaSequence)
{
printf("Enter the sequence.");
scanf("%s", dnaSequence);
}
So I figured /n would be in the last position of the array if its less than 50. So I have this for loop...
for(i = 0; i<length || dnaSequence[i] == '\n'; i++)
{
switch(dnaSequence[i])
{
case 'A': aCount++;
break;
case 'a': aCount++;
break; //do this for g,c,t but for readability I removed them for this post.
default:
{
printf("Invalid Base %c\n", dnaSequence[i]);
break;
}
}
}
To read the string and count all a,g,t,c but print out any invalid bases. It does this till it finds the /n or it reaches the end of the array. It does it correctly for the string I entered, but then it just throws in random characters from the rest of the array for the last half and calls them all invalid if they are.
So just to illustrate what I'm talking about, here it is in action. Image
Any help?
The memory reserved for dnaSequence is dirty. scanf puts the read characters at the beginning but the end stays the same. You should check for the end of the c-string in the for loop.
for(i = 0; i<length && dnaSequence[i] != '\n' && dnaSequence[i] != '\0'; i++)
EDIT: Tt worth to mention that scanf does not read the end-of-line character \n. So checking for it is unnecessary.
for(i = 0; i < length && dnaSequence[i] != '\0'; i++)
Your logic in your for statement is bad. Your for will end when the conditional part of your for loop returns false.
Remember that for's syntax is:
for(initialization; conditional; increment)
Your conditional should be using an And, not an Or, since i
Try
for(i=0; i<length && dnaSequence[i] !='\0'; i++)
Related
Will it be too much to ask if I pray for an elucidation of the following codes from Line 7 onward? I have difficulty in comprehending how getchar() may differ from gets() or scanf() for the most parts. Why is it important to add an escape sequence, \n with it, when in my belief, the value inputting would be done in a horizontal form(as it is a 1D string)? The increment and then the immediate usage of decrement operator bewilder me too. Also, require help with the strcpy(). :|
If somebody has the time, I implore guidance. Thank you!
main()
{
char st[80], ch, word[15], lngst[15];
int i, l, j;
printf("\n Enter a sentence \n ");
i = 0;
while((st[i++] = getchar()) != '\n');
i--;
st[i] = '\0';
l = strlen(st);
i = 0; j = 0;
strcpy(word," ");
strcpy(lngst," ");
while(i <= l)
{
ch = st[i];
if(ch == ' ' || ch == '\0')
{
word[j] = '\0';
if(strlen(word) > strlen(lngst))
strcpy(lngst, word);
strcpy(word," ");
j = 0;
}
else
{
word[j] = ch;
j++;
}
i++;
}
printf("\n Longest word is %s", lngst);
printf("\n Press any key to continue...");
getch();
}
I can't say why the code is written as it is (there are other input options) but I can address some of your concerns:
Why is it important to add an escape sequence, \n?
This "newline" character is returned by getchar() when you hit the return/enter key (the typical 'signal' used to indicate you've done entering your line of text). Without checking for this, the getchar function would just keep (trying to) read in more characters.
How getchar() may differ from gets() or scanf()?
It is notoriously tricky to read in text that includes spaces using the scanf function (this SO Q/A may help), and the gets function has been declared obsolete (because it's dangerous). One could use fgets(st, 80, stdin) but, like I said, I can't comment on why the code is written exactly like it is.
The increment and then the immediate usage of decrement operator
bewilder me too.
The expression (st[i++] = getchar()) transfers the character read into the st array element indexed by i and afterwards increments the value of i, so the next call to getchar will put its result in the next array element. But, when the \n (newline) character has been read, i will have been incremented, ready for the next character - but there won't be one, so we then reduce it by one after we have finished our while loop.
Also, require help with the strcpy().
The call strcpy(dst, src) will copy all characters in the string src (up to and including the required nul terminator, '\0') into the dst string, replacing anything that is already there.
Feel free to ask for further clarification and/or explanation.
while((st[i++] = getchar()) != '\n');
has the same effect as
while (1) { // "infinite" loop
int tmp = getchar(); // get keypress
st[i] = tmp; // copy to string
i++; // update index
if (tmp == '\n') break; // exit the infinite loop after enter is processed
}
I've encountered a problem while trying to scan chars into an array.
This is the scan loop -
char letter[6] = {0};
for(int i = 0; i <= 5; i++)
{
scanf(" %c", &letter[i]);
}
The desired result is that if the input is shorter than 6 every element which doesn't receive a value from scanf while remains 0.
However if I try to input for example 3 chars I cannot continue in the program.
On the other hand when I try to input 3 chars from txt file the program works and I achieve the desired result.
I was wondering what is the correct way to fix this issue.
Thank you all in advance.
Code fails to detect '\n' (Enter) due to space in format.
" " in scanf(" %c",&letter[i]); consumes and discards all white space including '\n' so code loses a way to detect end-of-line.
Instead check if scan failed (stdin closed or rare input error) or if a '\n' was read, then break the loop.
for(int i=0; i<=5; i++) {
char ch;
if (scanf("%c", &ch) != 1 || ch == '\n') {
break;
}
letter[i] = (char) ch;
}
To insure letter[] is a string, leave the last element as a null character.
// for(int i=0; i<=5; i++) {
for(int i=0; i < 5; i++) {
I'm trying to print a string of chars from an array and end the loop whenever I press the "Enter" key.
int i;
char charArry[MAXARY];
printf("Input an array of chars: \n\n");
for (i = 0; i < MAXARY && charArry[i] != 13; i++)
{
scanf(" %c", &charArry[i]);
}
for (i = 0; i < MAXARY; i++)
{
printf(" %c", charArry[i]);
}
For some reason whenever I press the Enter key it just goes to a new line instead of breaking the loop. Any suggestions?
P.S
MAXARY is a constant for the array length, currently 20.
Your close to having this working. Whilst I agree the use of scanf should be avoided, see: Why does everyone say not to use scanf? What should I use instead?, the reason your program doesn't do what you expect is due to a logic error.
Your for loop states:
for (i = 0; i < MAXARY && charArry[i] != 13; i++)
Now recapping how a for loop works, you have:
1. initalization (i=0)
2. conditional check (i < MAXARY && charArry[i] != 13)
3. conditional block (scanf)
4. increment (i++)
5. return to 2
You'll note your charArray[i] != 13check is happening after i has been incremented. Hence your not checking against the character you just read but the next character in charArray[i]. This is why your never breaking your loop at the \r character.
A recommended fix would be:
for (i = 0; i < MAXARY; i++)
{
int result = scanf("%c", &charArry[i]);
if( result != 1 || charArry[i] == '\n' )
break;
}
Which checks scanf was successful and charArry when i is the character that was read.
Also note as chux has pointed out the \r character is a carrage return, not the newline. Hence this check will only work if your working on windows (as unix doesn't use \r). If you want to be platform independant use \n
For some reason whenever I press the Enter key it just goes to a new line instead of breaking the loop.
The space in the format scanf(" %c", &charArry[i]); directs scanf() to consume and discard all optional leading white-space. charArry[i] will never be assigned 13 as 13 is typically '\r', a white-space.
An enter key is usually translated to '\n'.
Do not test values that have not been assigned #Red Alert
// v---------v not assigned yet.
for (i = 0; i < MAXARY && charArry[i] != 13
Repaired code
int i;
char charArry[MAXARY];
printf("Input an array of chars: \n\n");
for (i = 0; i < MAXARY; i++) {
if (scanf("%c", &charArry[i]) != 1) break; // End of file or error occurred
// If enter key encountered
// Usualy the charArry[i] == '\r' is not needed.
if (charArry[i] == '\n' || charArry[i] == '\r') break;
}
// Only print out characters that were read.
int j;
for (j = 0; j < i; j++) {
printf("%c", charArry[j]);
}
I am very new here .. so please excuse me if my question is really unnecessary .. but I think the answer will help me have some faith in myself ..here are two code snippets ..one i got on the website c4learn.com ..
#include<stdio.h>
int main()
{
char s1[100], s2[100];
int i;
printf("\nEnter the string :");
gets(s1);
i = 0;
while (s1[i] != '\0')
{
s2[i] = s1[i];
i++;
}
s2[i] = '\0';
printf("\nCopied String is %s ", s2);
return (0);
}
and the other i wrote myself ..
#include<stdio.h>
int main()
{
char s1[100], s2[100];
int i;
printf("\n Enter the string 1");
gets(s1);
printf("\n Enter the string2");
gets(s2);
for(i=0;i<100;i++)
{
if (s1[i]!='\0')
{
s2[i]=s1[i];
}
}
s2[i]='\0';
printf("\n Copied string is %s ", s2);
return(0);``
}
the problem is while running the code on dev c++ .. the final printf displayed is showing some random characters at the end of the string .. Can anyone help me understand that and which is code is better ? the initial question was ... HOW WILL YOU COPY ONE STRING TO ANOTHER WITHOUT USING ANY INBUILT LIBRARIES ? thank you ..
Your code is not quite right:
Why do you ask for the user input for s2 if you then overwrite it, copying s1?
The for cycle you wrote doesn't stop when s1 is over (I mean the null terminator character '\0') so you are also copying all the chars remaining in s1 after '\0'. If the chars in the array are not initialized (and that's the case for chars after '\0') they of course might result in random characters.
So answering your question, the first code is the right way to do it.
Any way if you want to use a for cycle you could do:
for (i = 0; i < 100; i++) {
s2[i] = s1[i];
if (s1[i] == '\0')
break;
}
You have to break out of the loop when you reach the null terminator character \0. The first code breaks out of the while loop while you're code continues on until i == 100 skipping over the null character. This is why its printing garbage past the original string.
This is what you should do to break out after the null character.
for (i = 0; i < 100; i++) {
s2[i] = s1[i];
if (s1[i] == '\0') break;
}
In the second block of code, after exiting the for loop, i has a value of 100. So you're putting the 0 byte at index 100.
Since an array of size 100 has indexes 0 to 99, you're writing past the end of the array. That causes undefined behavior.
When you're inside of the for loop, you need to break out after you find the null byte.
Also, both programs use gets which is unsafe because it does not perform any bounds checking and may write past the end of the array.
I'm trying to get selected characters from one string into another. Everything looks okay, except the program keeps adding additional characters to the output. And it seems that it tends to add different number of these "unecessary" characters. Where might the problem be?
int main(void) {
int i,j=0;
char string[256];
char second_arr[256];
scanf("%255s", string);
for(i=0;i<256;i++){
if(string[i]=='('||string[i]=='['||string[i]=='{'){
second_arr[j]=string[i];
j++;
}
}
printf("%s", second_arr);
}
Say,
input: (hello)(}[} --->
Output:(([[H
Problem 1: You're not testing scanf for failure. It can return EOF, or zero to indicate the input didn't match your format string.
Problem 2: You're copying all 256 chars even if the user entered fewer, which means you're copying junk.
Problem 3: You're not adding a null terminator to second_arr.
Just do this:
if (scanf("%255s", string) != 1)
{
printf("scanf failed\n");
return 1;
}
for (i = 0; i < 256 && string[i]; i++) {
if(string[i]=='('||string[i]=='['||string[i]=='{'){
second_arr[j]=string[i];
j++;
}
}
second_arr[j] = '\0';
printf("%s", second_arr);
return 0;
Try this:
for (i=0; string[i]!=0; i++) // iterate the input string until the null-character
{
if (string[i] == '(' || string[i] == '[' || string[i] == '{')
second_arr[j++] = string[i];
}
second_arr[j] = 0; // set a null-character at the end of the output string
There is nothing to terminate the second string. Add
||string[i]=='\0'
to your conditions. Also break out of the loop when you see that null char, but only after you have copied it.
You should add at the end of second string second_arr the char '\n' to indicate its end.