The following call to sprintf fails when compiled for i386 arch. using the Android NDK. I have tried compiling with both GCC and clang, and the result is the same. I'm using android-ndk-r10e (with APP_STL set to gnustl_shared with GCC, c++_shared with clang). It works as (I?) intended when compiling for ARM with the same configuration, and furthermore when I'm compiling for i386 Linux with GCC 5.2.
int n = sprintf(buf, "\xc0%s", "test"); // n == 0, strlen(buf) == 0
After the call, buf is empty rather than containing the expected char sequence "\xc0test". sprintf appears to ignore everything after the first non-ASCII character. The following code writes "test" to buf, leaving out the last byte:
sprintf(buf, "%s\xc0", "test"); // strlen(buf) == 4
On the other hand, this works fine:
sprintf(buf, "%s", "test\xc0"); // strlen(buf) == 5
I'm perplexed.
This is known Android problem. The problem resides in Android libc implementation (Bionic), which is fairly incomplete in terms of conforming to standards. In particular, Bionic stdio implementation doesn't support non-ASCII characters properly.
This simple test prints strlen(buf)=4 when being built by Android NDK r10e:
#include <stdio.h>
#include <string.h>
int main()
{
char buf[256];
sprintf(buf, "%s\xc0", "test");
printf("strlen(buf)=%d\n", strlen(buf));
return 0;
}
Solution: use CrystaX NDK - alternative fork of the Google's Android NDK, where that problems were fixed. The example above works properly if being built by the CrystaX NDK 10.3.1:
strlen(buf)=5
Related
The below code fails to print the wide character:
#include <ncurses.h>
using namespace std;
int main(void){
initscr();
printw("█");
getch();
endwin();
}
This code seems to work on some computers and not others, although all the libraries are installed correctly.
(The terminal is capable of displaying extended char!)
I compiled this using:
g++ -std=c++14 widechartest.cpp -o widechar -lncursesw
Could somebody let me know what the problem is?
Thanks 8)
You didn't initialize the locale. The manual page points this out:
The library uses the locale which the calling program has initialized.
That is normally done with setlocale:
setlocale(LC_ALL, "");
If the locale is not initialized, the library assumes that characters
are printable as in ISO-8859-1, to work with certain legacy programs.
You should initialize the locale and not rely on specific details of
the library when the locale has not been setup.
I'm having a wicked time trying to find a bug in my system. It's literally
driving me mad.
System: Ubuntu 16.04 LTS, gcc&g++ 4.9, 5.3 5.4 available.
Essentially I was trying to compile some code for point cloud registration, I didn't update my machine, I started see that Boost for some reason had disabled threading, generating multiple errors that no threading libraries could be found. I back tracked everything to a section of the boost header looking at GLib definitions, I checked and it seems my compilers cannot see unistd.h in gcc or g++.
I checked the files and everything is there, but literally cannot be seen.
I tried using the -I flag to get the compilers to look in the directory.
Example c code.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
int main (int argc, char *argv[])
{
int fd1;
char buf[128];
fd1 = open(argv[1], O_WRONLY | O_CREAT);
if (fd1 == -1) {
perror("File cannot be opened");
return EXIT_FAILURE;
}
scanf("%127s", buf);
write(fd1, buf, strlen(buf));
close(fd1);
return 0;
}
If I try to compile using the command g++ test_unistd.cpp -o main, then I get
/home/user/test_unistd.cpp: In function ‘int main(int, char**)’:
/home/user/test_unistd.cpp:20:32: error: ‘write’ was not declared in this scope
write(fd1, buf, strlen(buf));
^
/home/user/test_unistd.cpp:22:14: error: ‘close’ was not declared in this scope
close(fd1);
All the files I can see are there, I can't seem to figure out what the problem is.
Writing up what we figured out in the comments:
There was an empty file at /usr/local/include/unistd.h on OP's system. /usr/local contains unmanaged files (e.g. things you install manually). Compilers check /usr/local/include first (before /usr/include), so you can use it to override system functionality. But because /usr/local/include/unistd.h was empty, including it had no effect (except for preventing the real unistd.h from being used).
Solution: Delete /usr/local/include/unistd.h. That way the real header at /usr/include/unistd.h can be found and used again.
The article Unicode apps in the MinGW-w64 wiki explains the following example for an Unicode application, e.g. _main.c_:
#define UNICODE
#define _UNICODE
#include <tchar.h>
int _tmain(int argc, TCHAR * argv[])
{
_tprintf(argv[1]);
return 0;
}
The above code makes use of tchar.h mapping, which allows it to both compile in Unicode and non-Unicode mode. [...] The -municode option is still required when linking if Unicode mode is used.
So I used
C:\> i686-w64-mingw32-gcc main.c -municode -o hello
_tmain.c:1:0: warning: "UNICODE" redefined
#define UNICODE
^
<command-line>:0:0: note: this is the location of the previous definition
to compile a Unicode application. But, when I run it, it returns
C:\> hello Süßer
S³▀er
So the Unicode string is wrong. I used the latest version 4.9.2 of MinGW-w64, i686 architecture and tried the Win32 and POSIX theads variants, both result in the same error. My operating system is 32-bit German Windows 7. When I used the Unicode codepage (chcp 65001), I have to use the font "Lucida Console". With this setting I get a similar error:
C:\> hello Süßer
S��er
I want to use a parameter with "ü" or "ß" in a Windows C++ program.
Solution
nwellnhof is right: The problem is the output on the console. This problem is explained in Unicode part 1: Windows console i/o approaches und Unicode part 2: UTF-8 stream mode. The latter gives a solution for Visual C++ - it worked also with Intel C++ 15. This blog post does "not yet consider the g++ compiler. All this code is Visual C++ specific. However, [the blog author has] done generally the same with g++, and [he] will probably discuss that in a third installment."
I want to open a file, which name is given by a parameter. This works simple, e. g. main.c:
#include <iostream>
#include <fstream>
using namespace std;
int main(int argc, char* argv[])
{
if ( argc > 1 ) {
// The output will be wrong, ...
cout << argv[1] << endl;
// but the name of this file will be right:
fstream fl_rsl(argv[1], ios::out);
fl_rsl.close();
}
return 0;
}
and the compilation without unicode mode
C:\> g++ main.cpp -o hello && hello Süßer
It's console output is still wrong, but the created filename is right. This is okay for me.
I have 3 computers, two of which use Windows 8. Using the latest version of MinGW's g++ (4.8.1-4) my hello world program freezes whenever I compile and run on the Windows 8 computers but not in Windows 7.
#include <iostream>
int main()
{
std::cout << "Hello, World!" <<std::endl;
return 0;
}
This compiles just fine in g++ but running a.exe will display "Hello, World!" then a window will pop up and say "a.exe has stopped working, Windows can check online for a solution to the program...." etc.
Has anybody seen this problem.
Also, I tried "std::cout << "Hello, World!\n" << std::flush;" and this has the same problem. It seems that every function that flushes the buffer causes a crash.
Following Eric's advice, I recompiled the program and ran it in gdb and got the following output:
Program received signal SIGILL, Illegal instruction.
0x00405065 in _Jv_RegisterClasses ()
In the second instance, the '\n' should cause an output flush in any case, although in Windows I believe console output is immediate (or perhaps automatic after a short timeout) in any case without an explicit flush.
I suggest the following experiments:
1) See if it is specific to the C++ library by using the C library (in MinGW Microsoft's C runtime is used rather than glibc):
#include <stdio.h>
int main()
{
printf( "Hello, World!\n" ) ;
return 0;
}
2) Eliminate the exit code by:
int main()
{
return 0;
}
3) No newline at all:
#include <iostream>
int main()
{
std::cout << "Hello, World! ;
return 0;
}
4) Try different compiler options such as optimisation levels, or -fno-builtin for example, or as suggested here: -static-libgcc -static-libstdc++ (although I doubt ``-static-libgcc` will itself have any effect since MinGW uses Microsoft's C runtime DLL and the static library is only available with Microsoft's tools).
I had the same issue and found after a long painful search that I had multiple versions of the mingw provided libstdc++-6.dll on my computer. One was part of the mingw installation the others were part of other installation packages (gnuplot and GIMP). As I had gnuplot in my PATH the compiled mingw exe it would use an older, incompatible version of this dll and crash with the described symptoms. I can, therefore, confirm Dietmar Kühl's suspicion. As suggested above linking the library statically obviously helps in this case as the library functions are included in the exe at compile time.
It is probably a stupid question but i was searching for the answer from about 3h.
¿How to compile 64-bit binary with (Dev-C++) MinGW?
I have readed that MinGW support 64bits by default, but i am unable to active this option.
I have tryed "-m64" but it say: "sorry, unimplemented: 64-bit mode not compiled in"
I am working on Dev-C++ on Windows-7
I know how to do it on MSVC++, but I don't want MSVC++ (cause of ethical issues)
What i am trying to compile, just for testing purpose:
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
// Test compiling mode
if (sizeof(void*) == 8) cout << "Compiling 64-bits" << endl;
else cout << "Compiling 32-bits" << endl;
return 0;
}
To build a 64-bit binary on windows you need the 64-bit version of the mingw compiler. Mingw-W64 is one possible distribution you can use. You can find a list of downloads here.
Additionally, you can also find Dev-C++ setup bundled with mingw 64-bit compiler under Orwell Dev-C++'s download section. Make sure you choose "TDM-GCC x64 4.7.1" either setup or portable.