♣ string 헤더파일을 include 해준다. 

    #include <string> ← 추가!


※ append : 문자열 추가 

⇒ 추가 하고자 하는 문자열이 기존 문자열 뒤에 추가됨.

사용법 : str.append("문자열");

* str += "문자열"; 또는 str = str + "문자열"; 도 같은 원리로 작동합니다.


※ assign : 문자열 대입

⇒ 해당 변수에 문자열을 할당.(변수 정의와 같음)

사용법 : str.assign("문자열");

* str = "문자열" 도 같은 원리로 작동합니다.


※ clear : 문자열 삭제

⇒ 해당 변수의 문자열을 삭제한다.

사용법 : str.clear();


※ compare : 문자열 비교

⇒ 해당 변수와 입력 된 문자열을 비교한다.

사용법 : str.compare(str2);

반환값 : str == str2 이면 0 반환 / str > str2 이면 1 반환 / str < str2 이면 -1 반환

(여기서 str > str2 는 대소 비교가 아니라 사전순으로 비교해서 앞, 뒤를 의미)


※ erase : 문자열 삭제

⇒ 해당 변수의 문자열을 삭제한다.(범위 지정 가능)

사용법 : str.erase(시작 위치, 끝 위치); 또는 str.erase(); 

(시작 위치와 끝 위치를 지정해주면 해당 범위의 인덱스의 문자열이 삭제된다. 매개변수 없이 호출하면 clear와 같은 동작)


※ find : 문자 위치 검색

⇒ 해당 변수의 문자열 중 검색하려는 문자의 위치를 반환.

사용법 : str.find('문자');


※ length : 문자열 길이

⇒ 해당 변수의 문자열의 길이를 반환.

사용법 : str.length();

(문자열의 길이는 null을 포함하지 않는다.)


※ to_string : int to string

⇒ int 변수를 string 변수로 변환 

사용법 : string str = to_string(정수)


※ atoi : string to int

⇒ string 변수를 int 변수로 변환

사용법 : int i = atoi(str.c_str());

(atoi 매개변수 인자가 char*이므로 c_str() 함수를 사용하여 변환 해 주어야 함)


※ reverse : 문자열 뒤집기

⇒ 문자열을 역순으로 뒤집는다.

사용법 : 

string s = "abc";

reverse(s.begin(), s.end()); // "cba" 출력




오타나 질문사항은 댓글로 달아주세요!

'C, C++' 카테고리의 다른 글

C/C++ 구조체 사용법 및 예제  (1) 2018.10.08
C/C++ 배열 사용법  (0) 2018.10.05
C 파일처리  (0) 2018.10.02
C++ 벡터 사용법  (2) 2018.09.26
C언어 포인터  (8) 2018.09.25
C++ 자바 상속 비교  (0) 2018.09.08
C 랜덤 - 난수 생성하기  (7) 2018.09.06
[C++] C# 연동하기 / C# dll 파일 만들기  (1) 2018.08.18


1. 개요

크롤링(Crawling) 이란? 

정식명칭은 Scraping 또는 Web Scraping 으로 웹 사이트에서 원하는 정보를 추출하는 것을 의미합니다. 보통 웹 사이트는 기본적으로 Html 기반입니다. 크롬에서 Ctrl + U 또는 우클릭 - 페이지 소스보기를 클릭하시면 다음과 같은 화면을 볼 수 있습니다.





네이버 금융 웹 사이트 소스코드


위 사진은 네이버 금융  https://finance.naver.com/ 홈페이지의 소소를 확인한 것입니다.



2. 활용

그렇다면 이 소스들을 가지고 우리는 무엇을 할 수 있을까요?

Html 소스들을 자세히 들여다 보시면 우리가 웹 사이트에서 보는 모든 정보들이 담겨있습니다.

이 정보들 중 원하는 정보만 가져와서 자신만의 프로그램에 사용하는 것 입니다.


불법아닙니까?

-> 크롤링 한 데이터를 소장하고 활용하는것 까지는 불법이 아닙니다. 다만, 영리를 위한 목적, 배포 시 문제가 될 수 있습니다. 후자의 경우 해당 사이트의 허락을 꼭 맡으시기 바랍니다.


예제로 네이버 금융 사이트에서 국제시장환율 란의 환율 데이터를 긁어와서 화면에 출력해 보겠습니다.




3. 소스코드





4. 실행화면





위 코드를 실행하면 다음과 같이 콘솔창에 크롤링 한 데이터가 출력됩니다.

프로그램에 따라 윈도우 창에 출력 할 수도 있고 변수에 저장하거나 데이터베이스에 저장 할 수 도 있겠습니다. 

사실 문자열을 조금만 다룰 줄 안다면 쉽게 처리 가능한 기술입니다. 





정보가 유익하셨다면 아래 공감버튼 눌러주시면 감사하겠습니다.

질문사항은 댓글로 달아주시면 성의껏 답변해드리겠습니다.



안드로이드로 카메라를 연동 및 제어 방법입니다.

소스코드는 주요소스코드만 첨부합니다.

설명은 주석을 참고하세요.



1. AndroidManifest.xml 에 접근 권한 추가


<!-- 카메라 권한 -->

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

<uses-permission android:name="android.permission.CAMERA" />


2. SnackBar로 접근 권한 설정


// 카메라 접근 권한

private static final int PERMISSIONS_REQUEST_CODE = 100;

String[] REQUEST_PERMISSIONS = {Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE};

private static final int CAMERA_FACING = Camera.CameraInfo.CAMERA_FACING_BACK;

private SurfaceView surfaceView; // 카메라 Preview 출력

private CameraPreview mCameraPreview; // 카메라 Preview

private View mLayout; // SnackBar 사용


// 화면 켜진 상태 유지

getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);


// 최초 카메라 Preview가 켜졌을 때

if(getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){

     int cameraPermission = ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA);

     int writeExternalStoragePermission = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);


     // 권한 허용 시

     if(cameraPermission == PackageManager.PERMISSION_GRANTED && writeExternalStoragePermission ==                    PackageManager.PERMISSION_GRANTED){

          startCamera(); // 카메라 Preview를 SurfaceView에 출력

     }

            

     // 권한 없을 시            

     else{         

          if(ActivityCompat.shouldShowRequestPermissionRationale(this, REQUEST_PERMISSIONS[0]) ||     

               ActivityCompat.shouldShowRequestPermissionRationale(this, REQUEST_PERMISSIONS[1])){        

               Snackbar.make(mLayout, "이 앱을 실행하려면 카메라와 외부 저장소 접근 권한이 필요합니다.",                   

                    Snackbar.LENGTH_INDEFINITE).setAction("확인", new View.OnClickListener(){                   

                    @Override                   

                    public void onClick(View v) {                    

                       ActivityCompat.requestPermissions(CameraAcitivity.this, REQUEST_PERMISSIONS, PERMISSIONS_REQUEST_CODE);         

                    }                  

               }).show();            

          }             

          else{ // 사용자가 퍼미션 거부 한 적이 없는 경우 퍼미션 요청                  

               ActivityCompat.requestPermissions(this, REQUEST_PERMISSIONS, PERMISSIONS_REQUEST_CODE);         

          }         

     }      

} else{ // 카메라 미 지원시        

     final Snackbar snackbar = Snackbar.make(mLayout, "디바이스가 카메라를 지원하지 않습니다.", Snackbar.LENGTH_INDEFINITE);         

     snackbar.setAction("확인", new View.OnClickListener() {             

          @Override            

          public void onClick(View v) {                

               snackbar.dismiss();            

          }         

     });        

     snackbar.show();    

}



3. 카메라 플래시 제어


flash_btn = (Button)findViewById(R.id.flash_btn); // 플래시 버튼 이벤트        

flash_btn.setOnClickListener(new View.OnClickListener() {

     @Override

     public void onClick(View v) {

          flash_count++;

          if(flash_count > 1)

               flash_count = 0;

     

          if(flash_count==1) { // 플래시 켜기

               CameraPreview.params.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);

               CameraPreview.mCamera.setParameters(CameraPreview.params);

               Toast.makeText(CameraAcitivity.this, "Camera Flash ON", Toast.LENGTH_SHORT).show();

          }

          else { // 플래시 끄기

               CameraPreview.params.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);

               CameraPreview.mCamera.setParameters(CameraPreview.params);

               Toast.makeText(CameraAcitivity.this, "Camera Flash OFF", Toast.LENGTH_SHORT).show();

          }

     }

});


4. 화면에 사각형 그리기


class DrawOn extends View{ // 사각형 그리기

    public DrawOn(Context context){

        super(context);

    }


    @Override

    protected void onDraw(Canvas canvas) {

        super.onDraw(canvas);


        Paint pt = new Paint();

        pt.setColor(Color.GREEN);

        pt.setStrokeWidth(5);


        canvas.drawLine(100,350,100,400, pt);

        canvas.drawLine(100,350,200,350, pt);


        canvas.drawLine(520,350,620,350, pt);

        canvas.drawLine(620,350,620,400, pt);


        canvas.drawLine(100,600,100,650, pt);

        canvas.drawLine(100,650,200,650, pt);


        canvas.drawLine(520,650,620,650, pt);

        canvas.drawLine(620,650,620,600, pt);

    }

}


5. SurfaceHoder 인터페이스


@Override

public void surfaceCreated(SurfaceHolder holder) {

// SurfaceView 생성시 호출 : 카메라 프리뷰 화면 출력 및 크기 회전 설정

    try{

        mCamera = Camera.open(mCameraID);

    }

    catch (Exception e){

        Log.e(TAG, "Camera" + mCameraID + " is not availabe : " + e.getMessage());

    }


    Camera.CameraInfo cameraInfo = new Camera.CameraInfo();

    Camera.getCameraInfo(mCameraID, cameraInfo);


    mCameraInfo = cameraInfo;

    mDisplayOrientation = mActivity.getWindowManager().getDefaultDisplay().getRotation();


    int orientation = calculatePreviewOrientation(mCameraInfo, mDisplayOrientation);

    mCamera.setDisplayOrientation(orientation);

    

    mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes();

    requestLayout();


    params = mCamera.getParameters();


    List<String> focusModes = params.getSupportedFocusModes();

    if(focusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO)){

        params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);

        mCamera.setParameters(params);

    }


    try{

        mCamera.setPreviewDisplay(holder);

        mCamera.startPreview();

        Log.d(TAG, "CAMERA Preview Started");

    }

    catch (IOException e){

        Log.d(TAG, "Error setting camera preview" + e.getMessage());

    }

}


@Override

public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

// SurfaceView 의 크기가 변경될 때 호출

    if(mHolder.getSurface() == null){

        Log.d(TAG, "Preview surface does not exist");

        return;

    }


    try{    

        mCamera.stopPreview();

        Log.d(TAG, "Preview Stopped");

    }

    catch(Exception e) {

        Log.d(TAG, "Error stating camera preview : " + e.getMessage());

    }


    int orientation = calculatePreviewOrientation(mCameraInfo, mDisplayOrientation);

    mCamera.setDisplayOrientation(orientation);


    try{

        mCamera.setPreviewDisplay(mHolder);

        mCamera.startPreview();

        Log.d(TAG, "Camera preview started");

    }

    catch(Exception e){

        Log.d(TAG, "Error stating camrea preview : " + e.getMessage());

    }

}


@Override

public void surfaceDestroyed(SurfaceHolder holder) {

// SurfaceView 종료시 호출

    if(mCamera!=null){

        if(isPreview) 

            mCamera.stopPreview();

        mCamera.release();

        mCamera = null;

        isPreview = false;

    }

}


6. 이미지 저장하기


// 이미지 저장

private class SaveImageTask extends AsyncTask<byte[], Void, Void> {

@Override

protected Void doInBackground(byte[]... data) {

    FileOutputStream outStream = null;

    try {

        File path = new File (Environment.getExternalStorageDirectory().getAbsolutePath() + "/camtest");

        if (!path.exists()) {

            path.mkdirs();

        }

        String fileName = String.format("%d.jpg", System.currentTimeMillis());

        File outputFile = new File(path, fileName);


        outStream = new FileOutputStream(outputFile);

        outStream.write(data[0]);

        outStream.flush();

        outStream.close();


        Log.d(TAG, "onPictureTaken - wrote bytes: " + data.length + " to " + outputFile.getAbsolutePath());

        mCamera.startPreview();

        // 갤러리에 반영

        Intent mediaScanIntent = new Intent( Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);

        mediaScanIntent.setData(Uri.fromFile(outputFile));

        getContext().sendBroadcast(mediaScanIntent);


        try {

            mCamera.setPreviewDisplay(mHolder);

            mCamera.startPreview();

            Log.d(TAG, "Camera preview started.");

        } catch (Exception e) {

            Log.d(TAG, "Error starting camera preview: " + e.getMessage());

        }

    } catch (FileNotFoundException e) {

        e.printStackTrace();

    } catch (IOException e) {

        e.printStackTrace();

    }

    return null;

    }

}



* 실행화면




다음번엔 제어한 카메라 화면과 Tesseract-OCR을 사용해 자동차 번호판 인식 어플리케이션을 제작해보겠습니다.


* 참고 글

SurfaceView 화면 캡쳐하기

Bitmap 이진화 처리





to Top