Scanf missed line - scanf

I wrote a test program which should take in a 3x3 matrix of characters and output the entered matrix. However, I have to enter 4 lines in order for the program to produce the corresponding matrix. I have looked up problems on the scanf function, but none of the solutions I tried seemed to work...Could you help me out with this?
My code:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char a[3][3];
int i,j;
for(i=0;i<3;++i)
{
for(j=0;j<3;++j)
{
scanf("%c",&a[i][j]);
}
scanf("\n");
}
for(i=0;i<3;++i)
{
for(j=0;j<3;++j)
{
printf("%c",a[i][j]);
}
printf("\n");
}
system("PAUSE");
return(0); }

scanf("%c",...) get the whitespaces and the \n. You can solve it in many ways:
If you read like a b c
for(i=0;i<3;++i)
{
for(j=0;j<3;++j)
{
scanf("%c",&a[i][j]);
cin.get(); //Get the spaces after each character and the \n at the end of each line
}
}
or you can simple use cin (read char/string inputs with scanf is always a problem)
for(i=0;i<3;++i)
{
for(j=0;j<3;++j)
{
cin >> a[i][j];
}
}
if you are reading like abc, you only have to substitute your scanf("\n") for a cin.get()

#João Menighin's answer surely works. If you want to avoid c++, this would work:
for(i=0;i<3;++i)
{
for(j=0;j<3;++j)
{
scanf(" %c",&a[i][j]);
}
}
Although it would ignore ALL whitespace: both abc and a b c would be interpreted to be equivalent.

try adding a white space in your scanf right after the "
scanf(" %c",&a[i][j]);
I had the same problem in a two-dimension matrix and it worked for me.
I have no idea why though!!! I just spent 1 hour in front of my laptop trying different things...

Have tried your and IT WORKED. Although, I did make a few changes per comments:
#include <stdio.h> // added, but that shouldn't matter
main()
{
char a[3][3];
int i,j;
for(i=0;i<3;++i)
{
for(j=0;j<3;++j)
{
scanf("%c",&a[i][j]);
}
//scanf("\n"); // not necessary, see below
}
for(i=0;i<3;++i)
{
for(j=0;j<3;++j)
{
printf(" %c",a[i][j]);
}
printf("\n");
}
return(0);
}
Compiled and ran this code on Eclipse/Microsoft C Compiler and entered series of characters followed by enter.
abcdefghi
a b c
d e f
g h i
The point of confusion might be that scanf pulls the data from a console buffer. Typically, (although you can work around this) that buffer is returned to your program when you press enter. Also, the format specifier of %c also accepts blanks. Thus, I tried a second run with the following input and output.
a b c d e
a b
c
d e
You can tell the spaces were read and stored as well as the letters.
Hope this helps.

Related

Extracting between two strings with sed until the first occurrence

Can someone explain why I am getting different outcome while using the same command? I have 2 c++ files:
1st one(ax.h)
int iseven(int a);
int sum(float a, int b);
2nd one(ax.cpp)
//Definicija
int iseven(int a) {
if (a%2==0){
return 1;
else
return 0;}
float sum(float a, int b) {
return a + (float)b;
}
Why is it when I use the command:
sed -n '/iseven/,/}/p' ax.cpp
My output only does what I want and it print the text between iseven and the first occurrence of} ->
int iseven(int a) {
if (a%2==0){
return 1;
else
return 0;}
But when I use the same command(sed -n '/iseven/,/)/p' ax.h) on my 1st file(ax.h), it prints everything out:
int iseven(int a);
int sum(float a, int b);
And what I was expecting was int iseven(int a);
When you use
/start/,/end/ as the address in a sed command, it starts searching for end on the next line after the match of start. So you can't use a pattern range when the end pattern is on the same line as the start pattern.
You could just use /iseven/p to match just those lines in ax.h, unless you need to allow for declarations to be spread over multiple lines. If you need to handle both single-line and multi-line declarations, there might be a way using the hold space, but I'm not an advanced enough sed user to show how to do it.

1mpl3m3nt vector stack & output a stored&counted item

Here's my code:
I currently have everything the user enters dumped into the stack and sorted, but I don't how/where to go from here. I tried solving it with a count variable, but my solution isn't proper (it should output "2 dog" only once if the user enters dog twice). If anybody can help or knows a way to solve this, please give an example.
There are multiple ways to do this. The easiest is a simple use of std::map:
#include <iostream>
#include <string>
#include <map>
int main()
{
std::map<std::string, unsigned int> mymap;
std::string s;
while (std::getline(std::cin, s) && !s.empty() && s != "END")
++mymap[s];
for (auto const& pr : mymap)
std::cout << pr.second << ':' << pr.first << '\n';
}
How it works
Each line is read, and if successful (not eof, not empty, and not equivalent to "END") is used for updating an entry in the map.
Per the documentation for std::map::operator [], if the requisite key is not already present in the map, it is added, and mapped-to value is value-initialized. For unsigned int that means the initial value is 0.
From there, the increment is applied to the returned unsigned int reference, which for a new element, results in the value 1, for existing elements, it simply increments the prior value.
This continues until the loop terminates.
Upon termination of the loop the results are reported in lexicographical order, preceded by their count.
Input
one
two
three
four
three
one
one
one
two
END
Output
1:four
4:one
2:three
2:two
If you wanted to sort the output based on count, more work would need to be done, but it isn't difficult. A set of pairs from the map, inverted so the count is first, the string second, makes short work of that:
#include <iostream>
#include <string>
#include <map>
#include <set>
int main()
{
std::map<std::string, unsigned int> mymap;
std::string s;
while (std::getline(std::cin, s) && !s.empty() && s != "END")
++mymap[s];
std::set<std::pair<unsigned int, std::string>> ms;
for (auto const& pr : mymap)
ms.insert(std::make_pair(pr.second, pr.first));
for (auto const& pr : ms)
std::cout << pr.first << ':' << pr.second << '\n';
}
An example run appears below:
Input
one
two
three
four
three
one
one
one
two
END
Output
1:four
2:three
2:two
4:one
Use std::map as mentioned in comment:
std::map<std::string, unsigned int> countMap;
while(enter!=endString){
getline(cin,enter);
countMap[enter]++; // Operator `[]` enters a new key if not present and
// default initializes the value.
//, else fetches and increases the corresponding value
}
// coutMap[str] gives the number of times `str` entered.
You should use map. But if you are searching for another answer, use a search over all elements.
after you read all elements from input, start looping over vector. get first element, store its value and remove it then check other size-1 elements to see if they are equal to this one. if yes, add counter and remove the item from vector.
Notice that size has decreased. now again do the same till size becomes 0.

swscanf return wrong result

i use embarcadero Xe7. I found that swscanf returns wrong result.
example
int _tmain(int argc, _TCHAR* argv[])
{
char *t1= " ";
wchar_t *t2= L" ";
int i1, i2;
i1= -1;
i1= sscanf (t1, "%d", &i2);
if(i1!=EOF)
printf("sscanf output i1=%d i2=%d\n", i1, i2);
else
printf("sscanf EOF\n");
i1= swscanf(t2, L"%d", &i2);
if(i1!=EOF)
printf("swscanf output i1=%d i2=%d\n", i1, i2);
else
printf("swscanf EOF\n");
return 0;
}
the result:
sscanf EOF
swscanf output i1=1 i2=0
The first result is ok. But the second is wrong.
This is a bug. This behaviour of swscanf() contradicts the C11 standard:
7.29.2.4/3 The swscanf function returns the value of the macro EOF if an input failure occurs before the first conversion (if any) has
completed. Otherwise, the swscanf function returns the number of input
items assigned, which can be fewer than provided for, or even zero, in
the event of an early matching failure.
Clearly, here it fails before the first conversion has started.
It also contradicts the XE7 sscanf/swscanf documentation:
If sscanf attempts to read at end-of-string, it returns EOF.
And again, clearly, here it attempts to read end of string.
There is no bug report for now on EDN. You should file one.
*Workaround: process the cases i1==EOF and i1==0 together, as in both cases you can't exploit the content of any variable.

Unexpected output from lex program

I have written a simple lex program to perform average of positive numbers , the program is compiling fine but i'm not able to get the expected output.I'm passing the input to the program from a file by giving filename as a commandline argument.The output of the lex program is blank showing no result , i'm a beginner in lex and any help would be appreciated . I have attached the code below. The code is written in redhat linux kernel version 2.4.
%{
#include <stdio.h>
#include <stdlib.h>
%}
%%
[0-9]+ return atoi(yytext);
%%
void main()
{
int val, total = 0, n = 0;
while ( (val = yylex()) > 0 ) {
total += val;
n++;
}
if (n > 0) printf(“ave = %d\n”, total/n);
}
The input file contains numbers 3,6 and 4 and the name of the file is passed as command line argument.
./a.out < input
Your program works for me. I'm a bit suspicious of yywrap missing, so you probably link with the -lfl (or something alike) option. This library contains a yywrap and a main. Even though I'm not able to reproduce what you see, I'm wary that maybe the main from libfl is used. I'm assuming you do get any newlines in the input file on the output. Different linkers have different ways of resolving multiple occurrences of the same symbol.
All in all I think you have to look for the problem in the way your program is built, because the specification seems ok. If you add int yywrap(void) { return 1; } after your main, then you can do without libfl, which is what I would advise any user of lex and gnu-flex.

realloc():invalid next size

so I have some code that works fine with small text files but crashes with larger ones. The point of the code is to take a file and a parameter n, parse through the code and save everything in a 2d array in chucks of size n. So buffer[0][0]through [0][n-1] should hold n characters, and buffer[1][0]through [1][n-1] should hold the next n chunk, and so on. My code works when the file only has a few words, but with a larger file I get an error saying realloc():invalid next size. Any ideas why? Here is my code.
void bsort(int n)
{
int numwords= 0;
int numlets=0;
char ** buffer=(char**)malloc(numwords*n);
while (!feof(stdin))
{
char l= getchar();
if (l!= EOF)
{
if (numlets%n==0)
{
numwords=numwords+1;
buffer=(char**)realloc(buffer,numwords*n);
if(!buffer)
{
printf("Allocation error!");
}
buffer[numwords-1]= (char*) malloc (n);
buffer[numwords-1][numlets%n]=l;
// printf("%c", buffer[numwords-1][numlets%n]);
numlets=numlets+1;
}
}
int i,j;
for (i=0; i < numwords; i++)
{
for(j=0; j< n; j++)
{
printf("%c",buffer[i][j]);
}
}
It looks as if each time you get a character, you are reallocating your buffer. That seems a little off to me. Have you thought of allocating some space, doing a memset to \0, and just managing the current size and buffer size separately?
It may be that realloc is having issues with a pointer to nothing at first. If it fails after the first character input, you might be having issues with your first malloc(). Pre-allocating some space would solve that.
AFAIK, malloc(0) is not guaranteed to return a useful pointer you can realloc().
The documentation only guarantees that malloc(0) returns either null or a pointer that can safely be used to call free().