2011. 4. 22. 17:48

갤럭시 탭 해상도에 맞추기

갤럭시 탭 에뮬레이터 환경 설정이 완료된 후에도,
실제 실행을 해보면, 기존의 작은 해상도의 프로그램 화면이 그대로 작게 나오게 된다.
이때 매니페스트 설정을 통해, 프로그램 화면을 꽉 채울 수 있게 한다.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.MyFinancer.Play"
      android:versionCode="1"
      android:versionName="1.0"

      >

      <supports-screens android:largeScreens="true"
                                  android:anyDensity="true" />


    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".MyFinancerActivity"
                  android:label="@string/app_name"
                   android:screenOrientation="portrait"> 
                       -> ※ 참고 : 가로, 세로 회전을 고정시켜 주는 코드
   <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
           
        </activity>

    </application>
</manifest>



 [TIP] AndroidManifest란?                                       출저 및 링크 : http://tigerwoods.tistory.com/4

프로젝트폴더\ 밑에 생성 되는 AndroidManifest.xml는 간단히 말해 xml 문서 형식의 어플리케이션 명세서이다.

즉, 어플리케이션이 어떤 컴포넌트(Activity, Service, Content provider 등)을 포함하는지, 그 컴포넌트들이 어떤 구성을 통해 어플리케이션을 이루는지 (ex. 어떤 activity가 디바이스의 메인메뉴에 위치할지, 다른말로 어플리케이션 Launcher가 될지 여부 등), 또는 각종 제약 등이 메니페스트에 기록된다.

안드로이드 프로젝트를 생성하면 기본 메니페스트 파일이 생성되며, 아주 간단한 어플리케이션의 경우 수정할 필요가 없을 수도 있지만, 일반적인 어플리케이션의 경우 조금~많이 수정/내용 추가를 요 할 수도 있다. 참고로 안드로이드 SDK 내부에 포함된 API Demo suite 예제의 경우 1000라인이 넘는 큰 메니페스트 파일이 재공된다.
 


2009. 6. 3. 17:48

구조체를 파일에 읽거나 쓸 때 알고 쓰자.

보통 구조체를 통해 파일을 읽고 쓸 수 있는 것은 알 것이다.
fwrite(&somestruct, sizeof (somestruct), 1, fp);
형식으로 쓰면 되는데 만약 구조체가 포인터( char*타입의 문자열이나 다른 구조체를 가리키고 있는 포인터)
포함하고 있다면 파일내의 데이터는 단지 주소값만 저장되기 때문에
fread가 이루어진다 해도 주소값만 저장되지 주소값이 가르키고 있는 값은 저장되지 않는다.
밑의 코드 예를 보자.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define FILENAME1 "test1.txt"


typedef struct TmpData{

 int f;
 char arr[100];
 char* pArr;

}sTmpData;

typedef struct FileData{

 int a;
 int c;
 char b;
 sTmpData e;

}sData;


int WriteStFile(sData* in);
int ReadStFile(sData* out);


int main()
{
 sData WriteData = {2,33,'d'};
 sData ReadData;
 memset(&ReadData, 0, sizeof(ReadData) );

 // init WriteData
 WriteData.e.f = 100;
 strcpy( WriteData.e.arr, "aaa");
 WriteData.e.pArr = (char*)malloc( sizeof( WriteData.e.arr ) );
 strcpy( WriteData.e.pArr, "bbb");

 // Write File
 WriteStFile(&WriteData);

 // Read Structure Data from File
 ReadData.e.pArr = (char*)malloc( sizeof( WriteData.e.pArr ) );
 ReadStFile(&ReadData);

 // print
 printf("%d %d %c %d %s", ReadData.a, ReadData.c, ReadData.b, ReadData.e.f, ReadData.e.pArr);

 free( WriteData.e.pArr );
 
 system("pause");

 return 0;
}

int WriteStFile(sData *in)
{
 FILE* pFile = NULL;
 pFile = fopen( FILENAME1, "wb" );

 fwrite(in, sizeof(sData) , 1, pFile);

 fclose(pFile);

 return 0;
}

int ReadStFile(sData *out)
{
 FILE* pFile = NULL;
 pFile = fopen( FILENAME1, "rb" );

 fread(out, sizeof(sData) , 1, pFile);

 fclose(pFile);

 return 0;
}

실행은 하면 다음과 같은 결과가 뜬다.


위에 예상 결과와 달리 bbb라는 문자열이 잘 출력되고 있다. 무엇이 문제일까?
바로 WriteData 라는 구조체 변수에서 할당되었던 값을 의미하는 것이다.
즉 ReadData.e.pArr 가 가르키는 주소값과 WriteData.e.pArr 가 가르키는 주소값이 같기 때문에
아무 이상없이 출력되는 것이다. 혹 이것을 보고 bbb라는 문자열 또한 다른 메모리로 복사된 것으로
착각하기 쉽다.

위 코드에서 생성된 파일을 가지고 다음 코드를 주석처리한 다음 다시 실행해보자.

WriteData.e.pArr = (char*)malloc( sizeof( WriteData.e.arr ) );
strcpy( WriteData.e.pArr, "bbb");

결과를 보면


메모리에 값이 없거나 쓰레기 값, 또는 다른 곳에서 쓰고 있는 값을 가지고 올 수도 있는 것이다.

또한 많이 하는 실수는 메모리 해제에 있다.
같은 메모리를 가르키고 있는 상태를 그대로 쓴다면 메모리 해제에 있어 다음과 같은 실수를 저지를 수 있다.

 free( WriteData.e.pArr );
 free( ReadData.e.pArr );


즉 같은 메모리 주소를 가지고 두번 메모리 해제를 하기 때문에 힙 에러가 나는 것이다.

마지막으로 데이터 파일의 이식성을 위해서는 fopen()시 b 플러그를 사용하는 것이 좋다.
2009. 4. 29. 11:59

Flexible array member

표준(c90/c95)의 엄격한 해석에 따라 유용하게 사용할 수 있는 편범이 올바르지 않은 것으로 결론나자.
C99는 해당 편법을 정당하게 지원할 수 있는  flexible array member라는 기술을 새로 추가하였다.
즉 배열이 구조체나 공용체의 마지막 요소인 경우에 한해 선언 시에 그 크기를 명시하지 않고
나중에 할당받을 수 있도록 배려한 것이다. - 출처 : C언어 펀더멘탈 -

#include <stdio.h>
#include "stdlib.h"

struct A {
    int a;
    int b[];
};
   
int main()
{
    const int N = 10;
    int i;
   
    struct A* p = (A*)malloc(sizeof(struct A) + sizeof(int) * (N - 1));
   
    p->a = 100;
    for (i = 0; i < N; i++)
    {
        p->b[i] = i;
    }
       
    printf("%d %d %d\n", p->a, p->b[0], p->b[N-1]);
    for( int loop = 0 ; loop < N + 1 ; loop++ )
    {
           printf("%d %d\n", p->a, p->b[loop]);
    }   
    system("pause");
    //free(p);
   
    return 0;  
}