I have a text file full of text that i want to store in the form of strings in S
FILE *fp;
char str[200];
char **S = malloc( 200000*sizeof( char ) );
int i=0, j;
fp = fopen("S.txt" , "r");
while( fgets (str, 200, fp)!=NULL )
{
S[i] = str;
i++;
}
for(j=0;j<i;j++)
puts(S[j]);
fclose(fp);
But the problem is that the program only prints the last string of the list. I think that maybe i allocated the memory wrong(the malloc( 200000*sizeof( char ) ) its becouse the file contains up to 1000 strings of up to 200 characters)
FILE *fp;
char str[200];
/* <<<ATTENTION, READ HERE>>>
* Here, the allocation size is incorrect, one of two:
* You should use malloc( 200000 * sizeof (char *)); as you are
* allocating the pointers in the array, not the space for
* the strings
* You express (always safe) malloc( 200000 * sizeof *S ); This is
* a fake expression (not evaluated but to get the sizeof only)
*/
char **S = malloc( 200000 * sizeof *S );
int i=0, j;
fp = fopen("S.txt" , "r");
while( fgets (str, 200, fp)!=NULL )
{
/* <<<ATTENTION, READ HERE>>>
* the strdup(str); allocates memory (calling malloc itself)
* and copies the contents of the string in the allocated memory.
S[i] = strdup(str);
i++;
}
for(j=0;j<i;j++)
puts(S[j]);
fclose(fp);
With those two modifications your program will run safe (considering that you cannot allow files of more than 200000 lines of no more than 200 characters)
Your problem, not strdup()ing the string is that you finally made all strings point to the buffer, so the contents of the buffer after reading all the lines where the contents of the last line read. As all pointers pointed to the same place, you got as many copies of the last line (at double space, as fgets() doesn't take the \n off the string, but puts() does add a \n after printing the string passed.
NOTE
read how to create a minimum, complete and verifiable example, as you can easily eliminate the error if you decide to post just a snippet of code. Also, it makes more difficult for us to verify and check your error, or detect what is a typo from what is an error.
NOTE2
In case you want to return all the memory allocated by your program, you can do the following:
for(j = 0; j < i; j++)
free(S[j]); /* each malloc made inside strdup() */
free(S); /* the malloc you did at the beginning */
Related
I'm trying to create a function read_lines that takes a file *fp, a pointer to char** lines, and pointer to int num_lines. The function should insert each line of text into lines, and increase num_lines to however many lines the file has.
Its probably really simple but I've been trying to insert the text for several hours now.
This is what main.c would look like. Everything but read_lines is already defined and working. The file can have any amount of lines, tabs, and can even be only newlines.
(this is a homework assigment, so main.c and the function declaration must stay the same)
int main(int argc, char* argv[]){
char** lines = NULL;
int num_lines = 0;
FILE* fp = validate_input(argc, argv);
read_lines(fp, &lines, &num_lines);
print_lines(lines, num_lines);
free_lines(lines, num_lines);
fclose(fp);
return 0;
}
This is one of my attempts at trying to append lines, but I couldn't figure it out.
read_lines.c
void read_lines(FILE *fp, char ***lines, int *num_lines) {
int i;
int N = 0;
char s[200];
for (i=0; i<3; i++)
{
while(fgets(s, 200, fp)!=NULL){N++;}
char strings[50][200];
rewind(fp);
fgets(s, 200, fp);
strcpy(lines[i],s);
}
}
I'd appreciate any help at solving this, thanks.
You need to dynamically allocate the memory for each line as you read them. This is done with the malloc and realloc functions. malloc to allocate memory and realloc to resize the allocation.
The below code should do what you want (I haven't extensively tested it), but omits error checking that would be good practice.
void read_lines (FILE *fp, char ***lines, int *num_lines) {
// Initialize you number of lines variable
*num_lines = 0;
//Initialize the lines pointer
// NO ERROR CHECKING DONE HERE
*lines = malloc(sizeof(char*));
// create a fixed size buffer for reading from file
char s[200];
// Read from the file using fgets
while (fgets(s, 200, fp) != NULL) {
// THIS CODE ASSUMES ALL LINES ARE LESS THAN 200 CHARACTERS
// The memory to hold the line of text needs to be allocated
int length = strlen(s);
// Ensure there is space for the terminating null character
(*lines)[*num_lines] = malloc(sizeof(char) * (length + 1));
// The line needs to be copied from the buffer to the allocated memory
strcpy((*lines)[*num_lines], s);
// increment number of lines variable
*num_lines++;
// allocate space for another line in advance
*lines = realloc(*lines, sizeof(char*) * ((*num_lines) + 1));
}
// There will be an extra line pointer allocated in the loop
// Shrink the allocation to the appropriate size
*lines = realloc(*lines, sizeof(char*) * (*num_lines));
}
I am newer in C language. I want to create an array for my code to make some operation. As I said above, I am trying to learn how to use C language efficiently. My problem is this: I have a input file, let's say input.txt. I know that every line have 4 different things, 2 of them are string and 2 of them number. Also, I want to create a 2D array. But I do not know how many lines will be in input file. It depends on the user. So, I have to use malloc to make my array dynamically. So, can you help me about this problem? Maybe this is so easy, but I think reading file and create some array in C more difficult than other languages. It was so easy in Python :( I am leaving my code below. If you tell me my mistakes, I will be happy :)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char const *argv[]) {
char *arrChar;
int i;
char *str;
char *token;
arrChar = (char *) malloc( sizeof( char ) );
str = (char *) malloc( sizeof( char ) );
FILE *FileChars;
FileChars = fopen( argv[1], "r");
i = 0;
while ( fgets(str, sizeof str, FileChars) != NULL) {
int j;
for ( j = 0; j < 4; j++ ) {
token = strtok(str, ",");
arrChar[i][j] = token;
}
i++;
}
}
You need to understand precisely what the sizeof operator does, it doesn't return the size of a dynamically allocated memory block, it returns the size of a type, in case of arrays — roughly speaking — the size is part of the type specification and so it returns the number of bytes the array occupies.
In your case sizeof(char) is the size of the type char which is required to be exactl 1 by the (c-standard C Standard).
And sizeof(str) is the size of the type of str which is char *, that is, the size of a pointer. It's probably 4 or 8 depending on your current platform.
To solve this, you have to define a length to be used throughout your program as the length of the allocated chunk of memory, that after you make sure that the allocation was successful (see below).
A pointer to char can point to a sequence of elements that can be interpreted as a string if it is the correct sequence. A sequence of "printable" characters followed by a '\0' or null character is considered a string.
You have to pass NULL to strtok() after the first time, if you are going to be processing the same string.
You should CHECK that fopen() did return a valid stream, by comparing the return value to NULL.
The same as (5), for malloc() when allocation is not possible NULL is returned and using it as a valid pointer is undefined behavior.
All that said, here is what you probably wanted to write
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NUM_WORDS 100
int main(int argc, char const *argv[])
{
char *token;
char **words;
char line[100];
char *ptr;
size_t count;
FILE *file;
file = fopen( argv[1], "r");
// Check that we DID open the file
if (file == NULL) {
perror(argv[1]);
return EXIT_FAILURE;
}
// Allocate space for `NUM_WORDS' pointers
words = malloc(NUM_WORDS * sizeof(*words));
// Check that we did allocate enough memory
if (words == NULL) {
fclose(file);
return EXIT_FAILURE;
}
// We use `sizeof' here because `line' is an array
count = 0;
while ((count < NUM_WORDS) && (fgets(line, sizeof(line), file) != NULL)) {
ptr = line;
do {
token = strtok(ptr, ",");
// We need to copy the `token' because
// it lies within `line' and the '\0' will
// be replaced by the original character
// in subsequent callse to `strtok()'
//
// The `strdup()' will allocate enough space with
// `malloc()' then copy the contents of `token' to the
// allocated buffer, and return it, so we will
// have to call `free()' on every `words' element.
words[count++] = strdup(token);
// Subsequent calls to `strtok()' with the same
// string require that the first parameter is
// NULL
ptr = NULL;
} while ((count < NUM_WORDS) && (token != NULL));
}
// Now we may print the words and free the memory
for (size_t index = 0; index < count; ++index) {
puts(words[index]);
free(words[index]);
}
free(words);
return 0;
}
Note that the code above, makes sure that we don't exceed the capacity of the array of pointers words1. If you need to resize it, you will need to learn how to use realloc() and do it in a specialized routine so that your code doesn't become too complex.
1Note that the allocated space has no predefined interpretation, we do interpret it as an array but it's not an array in the c sense of an array definition, which line IS, having elements of type char, line can also be interpreted as a string given it has contents compatible with the defintion given in the (2) second point above.
I have a notepad file with approximately 150,000 words (representing a dictionary). I'm trying to scan in each word and print it to the console. This setup works fine:
void readDictionary(FILE *ifp, int numWords) {
fscanf(ifp, "%d", &numWords);
printf("%d\n", numWords);
int i;
char* words = (char*)malloc(20 * sizeof(char));
for(i = 0; i < numWords; i++) {
fscanf(ifp, "%s", words);
printf("%s\n", words);
}
}
However, this code obviously overwrites "words" each time it loops. I'm trying to get each word to save to a certain array element. I did the following but it instantly crashes (I changed the memory allocation to 2D because I read around here and it seems that is what I am supposed to do):
void readDictionary(FILE *ifp, int numWords) {
fscanf(ifp, "%d", &numWords);
printf("%d\n", numWords);
int i;
char** words = (char**)malloc(20 * sizeof(char*));
for(i = 0; i < numWords; i++) {
fscanf(ifp, "%s", words[i]);
printf("%s\n", words[i]);
}
}
Any help is appreciated. I've read around on many posts but haven't figured it out.
In your second version, you allocate space for 20 pointers, but you leave those pointers uninitialized and without anything to point to. I'm sure you can imagine how that presents a problem when you then try to read from your dictionary into the memory designated by one of those pointers.
It looks like you want to allocate space for numwords pointers
char** words = malloc(numwords * sizeof(*words));
, and for each of them, to allocate space for a word.
for(i = 0; i < numWords; i++) {
words[i] = malloc(20); // by definition, sizeof(char) == 1
// ...
Additionally, do check the return value of malloc(), which will be NULL in the event of allocation failure.
The first problem is you only allocated space for a list of words (ie. character pointers) but you didn't allocate space for the words themselves.
char** words = (char**)malloc(20 * sizeof(char*));
This allocates space for 20 character pointers and assigns it to words. Now words[i] has space for a character pointer but not for the characters.
words[i] contains garbage, because malloc does not initialize memory. When you pass it into fscanf, fscanf tries to use the garbage in words[i] as a memory location to write characters to. That's either going to corrupt some memory in the program, or more likely it tries to read a memory location is isn't allowed to and crashes. Either way, it's not good.
You have to allocate memory for the string, pass that to fscanf, and finally put that string into words[i].
char** words = malloc(numWords * sizeof(char*));
for(i = 0; i < numWords; i++) {
char *word = malloc(40 * sizeof(char));
fscanf(ifp, "%39s", word);
words[i] = word;
printf("%s\n", words[i]);
}
Note that I didn't cast the result of malloc, that's generally considered unnecessary.
Also note that I allocated space for numWords in the list. Your original only allocates space for 20 words, once it goes over that it'll start overwriting allocated memory and probably crash. As a rule of thumb, avoid constant memory allocations. Get used to dynamic memory allocation as quickly as you can.
Also note that I limited how many characters fscanf is allowed to read to the size of my buffer (minus one because of the null byte at the end of strings). Otherwise if your word list contained "Pneumonoultramicroscopicsilicovolcanoconiosis", 45 characters, it would overrun the word buffer and start scribbling on adjacent elements and that would be bad.
This leads to a new problem that are common to fscanf and scanf: partial reads. When the code above encounters "Pneumonoultramicroscopicsilicovolcanoconiosis" fscanf(ifp, "%39s", word); will read in the first 39 characters, "Pneumonoultramicroscopicsilicovolcanoco" and stop. The next call to fscanf will read "niosis". You'll store and print them as if they were two words. That's no good.
You could solve this by making the word buffer bigger, but now most words will be wasting a lot of memory.
scanf and fscanf have a whole lot of problems and are best avoided. Instead, it's best to read entire lines and parse them with sscanf. In this case you don't need to do any parsing, they're just strings, so getting the line will suffice.
fgets is the usual way to read a line, but that also requires that you try and guess how much memory you'll need to read in the line. To mitigate that, have a large line buffer, and copy the words out of it.
void strip_newline( char* string ) {
size_t len = strlen(string);
if( string[len-1] == '\n' ) {
string[len-1] = '\0';
}
}
...
int i;
/* The word list */
char** words = malloc(numWords * sizeof(char*));
/* The line buffer */
char *line = malloc(1024 * sizeof(char*));
for(i = 0; i < numWords; i++) {
/* Read into the line buffer */
fgets(line, 1024, ifp);
/* Strip the newline off, fgets() doesn't do that */
strip_newline(line);
/* Copy the line into words */
words[i] = strdup(line);
printf("%s\n", words[i]);
}
strdup won't copy all 1024 bytes, just enough for the word. This will result in using only the memory you need.
Making assumptions about files, like that they'll have a certain number of lines, is a recipe for problems. Even if the file says it contains a certain number of lines you should still verify that. Otherwise you'll get bizarre errors as you try to read past the end of the file. In this case, if the file has less than numWords it'll try to read garbage and probably crash. Instead, you should read the file until there's no more lines.
Normally this is done by checking the return value of fgets in a while loop.
int i;
for( i = 0; fgets(line, 1024, ifp) != NULL; i++ ) {
strip_newline(line);
words[i] = strdup(line);
printf("%s\n", words[i]);
}
This brings up a new problem, how do we know how big to make words? You don't. This brings us to growing and reallocating memory. This answer is getting very long, so I'll just sketch it.
char **readDictionary(FILE *ifp) {
/* Allocate a decent initial size for the list */
size_t list_size = 256;
char** words = malloc(list_size * sizeof(char*));
char *line = malloc(1024 * sizeof(char*));
size_t i;
for( i = 0; fgets(line, 1024, ifp) != NULL; i++ ) {
strip_newline(line);
/* If we're about to overflow the list, double its size */
if( i > list_size - 1 ) {
list_size *= 2;
words = realloc( words, list_size * sizeof(char*));
}
words[i] = strdup(line);
}
/* Null terminate the list so readers know when to stop */
words[i] = NULL;
return words;
}
int main() {
FILE *fp = fopen("/usr/share/dict/words", "r");
char **words = readDictionary(fp);
for( int i = 0; words[i] != NULL; i++ ) {
printf("%s\n", words[i]);
}
}
Now the list will start at size 256 and grow as needed. Doubling grows pretty fast without wasting too much memory. My /usr/share/dict/words has 235886 lines in it. That can be stored in 218 or 262144. 256 is 28 so it only requires 10 expensive calls to realloc to grow to the necessary size.
I've changed it to return the list, because there isn't much good in building the list if you're just going to use it immediately. This allows me to demonstrate another technique in working with dynamically sized lists, null termination. The last element in the list is set to NULL so anyone reading the list knows when to stop. This is safer and simpler than trying to pass the length around with the list.
That was a lot, but that's all the basic stuff you need to do when working with files in C. It's good to do it manually, but fortunately there are libraries out there which make doing this sort of thing a lot easier. For example, Gnome Lib provides a lot of basic functionality including arrays of pointers that automatically grow as needed.
What can be done in order to insert arrays into another array. I do happen to have a file which I'm looping through so my goal by now is to take each line within the file and put it into an array (An array of lines). Each line has some data related to a student and his/her tests results, for instance:
Mark Zuckerberg 10.0 5.5 9.7
Bill Gates 10.0 1.5 6.7
Example code:
FILE* file;
char buffer[256];
char arrayOfLines[500];
char line[256];
file= fopen("I:\\students.txt","r+");
/* Helps to iterate through each line */
while (fgets(buffer, sizeof(buffer), file)) {
//some logic to-be-coded
line = buffer; // just an idea does not work
arrayOfLines[i] = line; // just an idea does not work
}
Expected result:
arrayOfLines[] = {" Mark Zuckerberg 10.0 5.5 9.7", "Bill Gates 10.0
1.5 6.7" };
I certainly know this is somehow easy to achieve but after working with java for a long time it turned out to be a little bit tricky, could someone please help me out with this matter?
Everything works just fine when it comes to iterating and reading. However, when it comes to "playing" with each line it gets creepy. Perhaps I need to change my approach, any help would be welcomed.
Array names decay into pointers when you try to assign them. In order to copy the contents of buffer to another char[] variable, you'll have to use memcpy, strcpy or strncpy
Apart from that, you do have an issue with your arrayOfLines variable. It's not an array of lines. It's an array of 500 characters, so it's not even big enough to hold 2 lines, what you need is:
char array_of_lines[500][256];
And to copy the data, I'd use:
memcpy(aray_of_lines[i], buffer, sizeof buffer);//where `i` is the current line, starting at 0
It might be worth looking into malloc-ing the array of lines here, because this code requires 128,000 bytes of stack space to be available, just to accommodate the array_of_lines array, so I'd write:
char *array_of_lines[500];
//in the loop:
array_of_lines[i] = malloc(strlen(buffer) + 1);
//check for NULL, and all that
strncpy(array_of_lines[i], buffer, strlen(buffer));
#include <stdio.h>
#include <string.h>
int main( void ){
FILE *file = fopen("I:\\students.txt","r");
char buffer[256*500];
char *arrayOfLines[500];
char *line = buffer;
size_t buf_siz = sizeof(buffer);
int i=0, n;
while (fgets(line, buf_siz, file)) {
char *p = strchr(line, '\n');
if(p)
*p = '\0';//remove newline
else
p = strchr(line, '\0');
arrayOfLines[i++] = line;
buf_siz -= p - line + 1;
if(p + 1 == buffer + sizeof(buffer))
break;//buffer full!
line = p + 1;
}
fclose(file);
n = i;
for(i=0; i<n; ++i)
puts(arrayOfLines[i]);
return 0;
}
The task of this function is fairly straightforward. Given an array of char*, a pointer to a file, and a maximum word size, it reads through the file and copies each word one by one into the char* array. Since there's one word per line in the file, it makes sense to use \n as the break between words. So with that in mind, the code should be fairly simple to interpret:
void loadDictionary(char* strDictionary[], FILE* filePointer, int nMaxLetters)
{
int nNameCount= 0, nCursor = 0;
char* strCurrent;
char cCurrent;
//allocate space for a word
strCurrent = malloc(nMaxLetters * sizeof(char));
while ((cCurrent = fgetc(filePointer)) != EOF) {
if(cCurrent != '\n')
{
strCurrent[nCursor] = cCurrent;
nCursor++;
} else { //then we've reached the end of the line (word)
//add null termination to string
strCurrent[nCursor] = '\0'; //SEG FAULT
//copy string to dictionary
memcpy(strDictionary[nNameCount], strCurrent, strlen(strCurrent)+1);
//increment count
nNameCount++;
//reset the cursor
nCursor = 0;
}
}
}
This code generates a segmentation fault at the line where I call strCurrent[nCursor] = '\0';. I'm not sure why, because on the face of it, it seems like this operation should be no different from the operation in the other block, where I call strCurrent[nCursor] = cCurrent;. strCurrent should have allocated more than enough space to store all necessary characters. So, I'm somewhat at a loss. Help me figure this one out, guys.
Note: I think I would probably have an easier time using fgets instead of fgetc to accomplish this task. I might well switch to that; however, since I have encountered an error I don't understand, I don't want to leave it alone until I've understood it.
EDIT:
Someone pointed out that the error might occur in the memcpy operation, possibly due to strDictionary being improperly allocated. Here's the main block where strDictionary gets allocated. Perhaps I have made an error:
int main(int argc, char* argv[])
{
char** strDictionary;
FILE* filePointer;
int nResults = 0, nLines = 0, nNumLines, nMaxChars, i;
filePointer = fopen("dictionary.txt", "r");
//obtain the number of lines and the maximum word size of the dictionary
countLines(filePointer, &nNumLines, &nMaxChars);
//allocate memory for strDictionary
strDictionary = malloc(nNumLines * nMaxChars * sizeof(char));
printf("%d words in dictionary. Longest word is %d letters\n",
nNumLines, nMaxChars);
//Output here correctly prints: 1000 and 21
//reset the file pointer (not sure if this is a necessary step, but oh well)
filePointer = fopen("dictionary.txt", "r");
//load dictionary into memory
loadDictionary(strDictionary, filePointer, nMaxChars);
for (i=0; i<10; i++)
printf("%dth element of dictionary: %s\n", i, strDictionary[i]);
return 0;
}
EDIT 2:
OK, I decided to use fgets() instead of fgetc() to greatly simplify my function. I've also done what I thought was a correct malloc() operation for strDictionary. However, I'm still getting a seg fault. Here's the updated code:
void loadDictionary(char* strDictionary[], FILE* filePointer, int nMaxLetters)
{
printf("Call to loadDictionary. nMaxLetters = %d\n", nMaxLetters);
int nWordCount= 0, nCursor = 0;
char* strCurrent;
char cCurrent;
strCurrent = malloc(nMaxLetters); //allocate space for a word
while (fgets(strCurrent, nMaxLetters, filePointer) != NULL)
{
memcpy(strDictionary[nWordCount], strCurrent, strlen(strCurrent)+1);
nWordCount++;
}
}
int main(int argc, char* argv[])
{
char** strDictionary;
FILE* filePointer;
int nResults = 0, nLines = 0, nNumLines, nMaxChars, i;
filePointer = fopen("dictionary.txt", "r");
//count the lines in the file (works fine)
countLines(filePointer, &nNumLines, &nMaxChars);
//allocate space for the dictionary
strDictionary = malloc(nNumLines * sizeof(char*));
for (i = 0; i<nLines; i++)
strDictionary[i] = malloc(nMaxChars * sizeof(char));
printf("%d words in dictionary. Longest word is %d letters\n",
nNumLines, nMaxChars);
//load dictionary into array
filePointer = fopen("dictionary.txt", "r");
loadDictionary(strDictionary, filePointer, nMaxChars);
for (i=0; i<10; i++)
printf("%dth element of dictionary: %s\n", i, strDictionary[i]);
return 0;
}
Here:
char cCurrent;
...
while ((cCurrent = fgetc(filePointer)) != EOF) {
You are truncating the fgetc()'s value of type int to char. This may lead to the while condition not correctly recognizing EOF. cCurrent has to be int.
Here:
//allocate space for a word
strCurrent = malloc(nMaxLetters * sizeof(char));
nMaxLetters has to account for one extra character representing the string NUL terminator. Is it accounted for?
Btw, sizeof(char) is always 1.
Now, this parameter declaration:
char* strDictionary[]
is equivalent to this:
char** strDictionary
or, IOW, a pointer to a pointer to a char. That's because in C, arrays are never passed as parameters, only pointers to their first elements are, despite the deceptive syntax with the brackets suggesting something is an array.
This line:
memcpy(strDictionary[nNameCount], strCurrent, strlen(strCurrent)+1);
is going to take nNameCount'th pointer to a char and write character data where it points to.
But does the calling function allocate at least as many string buffers (of length nMaxLetters) as there are going to be lines in the file? Does it populate some array of pointers to char with the pointers to these buffers before passing this array into loadDictionary()? IOW, this code is expecting the caller to do something like this:
#define nMaxEntries 1000
char* dictionary[nMaxEntries];
int i;
FILE* f;
...
for (i = 0; i < nMaxEntries; i++)
dictionary[i] = malloc(nMaxLetters);
loadDictionary(dictionary, f, nMaxLetters);
Memory allocation failures must be checked in the above code. Also, I'd strongly suggest passing nMaxEntries into or using it in loadDictionary() so you don't overrun the array of pointers if the file has more lines than nMaxEntries. nNameCount should not grow beyond nMaxEntries.
UPDATE to the updated question...
Here:
char** strDictionary;
...
strDictionary = malloc(nNumLines * nMaxChars * sizeof(char));
You are not creating an array of pointers to char as loadDictionary() expects per the above analysis, you are creating a 2d array of char. And because of that the segfault most probably occurs not on this line:
strCurrent[nCursor] = '\0'; //SEG FAULT
but on the very next one, which may not be apparent in the debugger until you zoom in and look at the disassembly of the code:
//copy string to dictionary
memcpy(strDictionary[nNameCount], strCurrent, strlen(strCurrent)+1);
UPDATE2:
I don't understand why you now allocate space for nNumLines pointers:
strDictionary = malloc(nNumLines * sizeof(char*));
but of those nNumLines pointers you initialize nLines pointers (and nLines never becomes anything other than 0 if I'm reading your latest code correctly):
for (i = 0; i<nLines; i++)
strDictionary[i] = malloc(nMaxChars * sizeof(char));
What's the trick? Typo?